与上一篇文章相似
我正在寻找如何使用基于映射的有效方法分组
我在下面有一个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