熊猫按总和特定的列分组,并保留其他列

时间:2020-06-09 12:44:05

标签: python pandas pandas-groupby

我正在尝试做一些简单的事情... 我有一个数据框,并且尝试按特定列进行分组,输出数据框需要保留一列并求和另外两列。 下面是一个示例:

df:

User  Col1ToSum  Col2ToSum   ColToKeep
ABC     10         440         1.015
ABC     15         410         1.015
ABC     15        -200         1.015
ABA     100        110         2.24 
ABA     80        -10          2.24
AAA     40         10          nan
AAA     20         10          nan
BBB     10         15          nan
XYZ     10         10          1.1
XYZ     10         10          1.5 (note the 'ColToKeep' is different for user XYZ)

预期输出:

User  Col1ToSum  Col2ToSum   ColToKeep
ABC     45         650         1.015
ABA     180        100         2.24
AAA     60         20          nan
BBB     10         15          nan
XYZ     10         10          1.1
XYZ     10         10          1.5

我试图做:

  1. df.groupby(['User', 'ColToKeep'], as_index=False).mean() 不幸的是,它删除了ColToKeep为nan且要求和的两列都不是求和的所有记录。
  2. df.groupby(['User'], as_index=False)['Col1ToSum', 'Col2ToSum'].sum() 不幸的是,它正在输出df中删除“ ColToKeep”列
  3. df.groupby(['User', 'ColToKeep'], as_index=False)['Col1ToSum', 'Col2ToSum'].sum(),但与第1点相同)是删除ColToKeep为nan的记录

我之所以尝试按User和ColToKeep进行分组是因为如果User相同但我想拥有2条记录,而ColToKeep却不同。

我不确定为什么by by会删除nan值(可能是由于我缺乏熊猫经验)...

请问您能不能帮上忙,甚至可以解释为什么会发生这种情况?

2 个答案:

答案 0 :(得分:3)

熊猫支持groupby版本link中的1.1中的缺失值。

第一个想法是创建新的帮助程序列new,将缺少的值替换为某些字符串,例如miss,然后按new分组,按GroupBy.aggGroupBy.first进行汇总,最后按第一个reset_index删除帮助程序级别:

df = (df.assign(new= df['ColToKeep'].fillna('miss'))
       .groupby(['User', 'new'], sort=False)
       .agg({'Col1ToSum':'sum', 'Col2ToSum':'sum', 'ColToKeep':'first'})
       .reset_index(level=1, drop=True)
       .reset_index())
print (df)
  User  Col1ToSum  Col2ToSum  ColToKeep
0  ABC         40        650      1.015
1  ABA        180        100      2.240
2  AAA         60         20        NaN
3  BBB         10         15        NaN
4  XYZ         10         10      1.100
5  XYZ         10         10      1.500

另一个想法是将miss替换为NaN s:

df = (df.assign(ColToKeep = df['ColToKeep'].fillna('miss'))
       .groupby(['User', 'ColToKeep'], sort=False)[['Col1ToSum', 'Col2ToSum']].sum()
       .reset_index()
       .replace({'ColToKeep': {'miss':np.nan}}))
print (df)
  User  ColToKeep  Col1ToSum  Col2ToSum
0  ABC      1.015         40        650
1  ABA      2.240        180        100
2  AAA        NaN         60         20
3  BBB        NaN         10         15
4  XYZ      1.100         10         10
5  XYZ      1.500         10         10

答案 1 :(得分:1)

将“ ColToKeep”更改为字符串,然后使用您的代码。

In : df['ColToKeep'] = df['ColToKeep'].astype(str)

In : df.groupby(['User','ColToKeep'], as_index=False).sum()
Out: 
  User ColToKeep  Col1ToSum  Col2ToSum
0  AAA       nan         60         20
1  ABA      2.24        180        100
2  ABC     1.015         40        650
3  BBB       nan         10         15
4  XYZ       1.1         10         10
5  XYZ       1.5         10         10

如有必要,您可以通过以下方式将ColToKeep改回浮动状态:

df1 = df.groupby(['User','ColToKeep'], as_index=False).sum()

df1['ColToKeep'] = df1['ColToKeep'].astype(float)

print(df1)
  User  ColToKeep  Col1ToSum  Col2ToSum
0  AAA        NaN         60         20
1  ABA      2.240        180        100
2  ABC      1.015         40        650
3  BBB        NaN         10         15
4  XYZ      1.100         10         10
5  XYZ      1.500         10         10