我想计算每个相关组的平均值。每个名称都有两个组和一个值。我想定义每个名称的相关组是什么,然后获取该相关组的平均值。理由是我想确保该组有足够的实例来计算我的平均值,以确保它有意义。
我的原始数据集:
a=pd.DataFrame({'Name':['Jack','Peter','Jim','Alex','Dan','Chris'],
'Group':['A','B','C','C','A','A'],
'Sub Group':['a','b','b','c','c','c'],
'Value':[3,5,2,6,7,1]})
我的预期输出:
b=pd.DataFrame({'Name':['Jack','Peter','Jim','Alex','Dan','Chris'],
'Label':['A',np.nan,np.nan,'c','A',' A'],
'Average':[(3+7+1)/3,np.nan,np.nan,(6+7+1)/3,(3+7+1)/3,(3+7+1)/3]})
为了说明逻辑,这里是一个例子,我想首先检查每组中是否至少有三个人。我首先检查组,如果没有,则转到下一个子组。例如,Jack的“标签”为“A”,这是因为Group中有3个“A”,所以不需要检查Sub Group。对于Peter,我首先检查组中是否有“B”,没有。然后我进一步检查Sub Group中是否有三个“b”,也没有,所以Peter有一个NA的“标签”。对于Alex,按照同样的逻辑,组中只有两个“C”,所以我进入子组,子组中有三个“c”,所以Alex得到了“c”的“标签”。
至于平均值,Jack 得到的是“A”的平均值,即(3+7+1)/3,Alex 得到的是“c”的平均值,即(6+7+1)/3。
这就是我所做的:
a['Group Count']=a.groupby('Group')['Name'].transform('count')
a['Sub Group Count']=a.groupby('Sub Group')['Name'].transform('count')
a['Label']=np.where(a['Group Count']>=3,'Group', np.where(a['Sub Group Count']>=3,'Sub Group',np.nan))
a['Group Name']=np.where(a['Label']=='Group',a['Group'], np.where(a['Label']=='Sub Group',a['Sub Group'],np.nan))
group=a.groupby('Group')['Value'].mean().to_dict()
sub_group=a.groupby('Sub Group')['Value'].mean().to_dict()
a['Average']=np.where(a['Label']=='Group', a['Group Name'].map(group),
np.where( a['Label']=='Sub Group', a['Group Name'].map(sub_group),np.nan))
还有更优雅的解决方案吗?因为我在真实数据集中有多个组和十几个值,所以我需要计算平均值。
您可以定义一个函数来进行计算并将其应用到数据框上。
然后使用它。如果您还希望它内联完成,这里是一个示例:
您可以使用自定义函数
groupby.transform
andfunctools
的reduce
andpartial
:输出:
请注意,组的顺序很重要,如果您使用
groups = ['Sub Group', 'Group']
, thenc
将优先A
于最后两行:您可以根据需要定义任意数量的组,使用下面的示例和
groups = ['Group', 'Sub Group', 'Sub Sub Group']
:保留原始列(组除外)的变体:
输出:
怎么运行的
对于 if 中的每个名称
group
计算有效组的平均值:因此,您可以按顺序组合输出:
reduce
将此逻辑自动化为任意数量的组,相当于:并将
partial
该函数转换为绑定到(仅需要“col”)作为参数的avg_thresh
函数。a
这些函数不是严格必需的,但有助于缩短代码。