根据映射对特定列进行groupby和sum



与上一篇文章相似

我正在寻找如何使用基于映射的有效方法分组

我在下面有一个df:

当value为<30时为低值当值在30-70之间时,它是中等的当>70

|col1|col2|col3|col1_cat|col2_cat|col3_cat
----------------------------------------------------
0  |29  |80  |56  |low     |high    |medium
1  |19  |50  |88  |low     |medium  |high

col1映射到col1_cat,依此类推如果我在另一个数据框中有如下映射,我如何一次对组上的所有列进行分组求和

name | group
-------------
col1 | col1_cat
col2 | col2_cat
col3 | col3_cat

要求的最终输出如下:

cat     | col1_sum | col2_sum | col3_sum
_______________________________________
high    |          |  80      | 88
medium  |          |  50      | 56
low     | 48       |          | 

尝试上一个类似问题的答案

我认为你想要达到的目标可以通过以下方式实现:

df = pd.DataFrame({
'col1': [10,20,50,20,30,140,50,80,20],
'col2': [40,60,10,70,110,10,340,10, 50]
})
def map_col(x):
if x<30:
return 'low'
elif x<70:
return 'medium'
else:
return 'high'
df['col1_cat'] = df['col1'].map(map_col)
df['col2_cat'] = df['col2'].map(map_col)

然后分组两次:

df.groupby(['col1_cat', 'col2_cat']).agg('sum').groupby('col2_cat').agg('sum')

如果您在mapping_df中有映射数据框,您可以尝试:

mapping_dict = mapping_df.set_index('name')['group'].to_dict()
def fn(x):
rv = {}
for k, v in mapping_dict.items():
rv[(k, x[v])] =  rv.get((k, x[v]), 0) + x[k]
return pd.Series(rv)

df_out = df.apply(fn, axis=1).sum().unstack(level=0).add_suffix('_sum')
print(df_out)

打印:

col1_sum  col2_sum  col3_sum
high         NaN      80.0      88.0
low         48.0       NaN       NaN
medium       NaN      50.0      56.0

最新更新