我想计算每个相关组的平均值。每个名称都有两个组和一个值。我想定义每个名称的相关组是什么,然后获取该相关组的平均值。理由是我想确保该组有足够的实例来计算我的平均值,以确保它有意义。
我的原始数据集:
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))
还有更优雅的解决方案吗?因为我在真实数据集中有多个组和十几个值,所以我需要计算平均值。
您可以定义一个函数来进行计算并将其应用到您的数据框上。
# Function to calculate average based on group or subgroup
def calculate_average(group):
if group['Group'].count() >= 3:
return group['Value'].mean()
elif group['Sub Group'].count() >= 3:
return group['Value'].mean()
else:
return np.nan
然后使用它。如果您还希望它内联完成,这里有一个示例:
# Calculate averages
a['Average'] = a.groupby(['Group', 'Sub Group']).apply(calculate_average).reset_index(level=[0,1], drop=True)
# Reset Label for those groups that don't meet the threshold
a.loc[a['Average'].isna(), 'Label'] = np.nan
print(a[['Name', 'Label', 'Average']])