定义对等组并计算对等组分析

问题描述 投票:0回答:1

我想计算每个相关组的平均值。每个名称都有两个组和一个值。我想定义每个名称的相关组是什么,然后获取该相关组的平均值。理由是我想确保该组有足够的实例来计算我的平均值,以确保它有意义。

我的原始数据集:

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))

还有更优雅的解决方案吗?因为我在真实数据集中有多个组和十几个值,所以我需要计算平均值。

python pandas
1个回答
0
投票

您可以定义一个函数来进行计算并将其应用到您的数据框上。

# 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']])
© www.soinside.com 2019 - 2024. All rights reserved.