【问题标题】:Pandas groupby with MultiIndex columns and different levels具有 MultiIndex 列和不同级别的 Pandas groupby
【发布时间】:2018-09-04 13:54:00
【问题描述】:

我想在 MultiIndex 数据帧上进行分组,计算 df 中每个 user2 的每一列的出现次数:

>>> df
      user1 user2 count
                   0             1      2
                   a      x      d      a 
    0  2     6     0      1      0      0
    1  4     6     0      0      0      3
    2  21    76    2      0      1      0
    3  5     18    0      0      0      0

注意user1user2count 处于同一级别(合并的副作用)。

期望的输出

  user2 count
        0              1      2
        a       x      d      a 
0  6    0       1      0      1
1  76   1       0      0      0    
3  18   0       0      0      0  

我试过了

>>> df.groupby(['user2','count'])

但我明白了

ValueError: Grouper for 'count' not 1-dimensional

生成器代码:

df = pd.DataFrame({'user1':[2,4,21,21],'user2':[6,6,76,76],'param1':[0,2,0,1],'param2':['x','a','a','d'],'count':[1,3,2,1]}, columns=['user1','user2','param1','param2','count'])
df = df.set_index(['user1','user2','param1','param2'])
df = df.unstack([2,3]).sort_index(axis=1).reset_index()

df2 = pd.DataFrame({'user1':[2,5,21],'user2':[6,18,76]})
df2.columns = pd.MultiIndex.from_product([df2.columns, [''],['']])
final_df = df2.merge(df, on=['user1','user2'], how='outer').fillna(0)

【问题讨论】:

  • 为什么你的数据是这样的?我的意思是计算有水平
  • @Yuca 它是将数据框与 MultiIndex 列和常规数据框合并的产物

标签: pandas


【解决方案1】:

IIUC,你想要的:

final_df.where(final_df>0).groupby('user2').count().drop('user1', axis=1).reset_index()

输出:

  user2 count         
            0     1  2
            a  x  d  a
0     6     0  1  0  1
1    18     0  0  0  0
2    76     1  0  1  0

避免删除列,只选择'count',并将函数更改为sum

final_df.where(final_df>0).groupby('user2').sum()[['count']].reset_index()

输出:

  user2 count               
            0         1    2
            a    x    d    a
0     6   0.0  1.0  0.0  3.0
1    18   0.0  0.0  0.0  0.0
2    76   2.0  0.0  1.0  0.0

为了避免删除 user2 也等于零值。

final_df[['count']].where(final_df[['count']]>0)\ .groupby(final_df.user2).sum().reset_index()

【讨论】:

  • 谢谢,斯科特,这行得通!我还可以将count 替换为任何其他函数,例如sum。但是,是否有手动删除其他列的解决方法?在完整的数据框(这是一个示例)中,我想删除很多列,我不想一一写下来。
  • 谢谢斯科特。此外,这里还有另一个 sn-p,它根据您写的内容使用 agg 函数:final_df.where(final_df>0).groupby('user2').agg(fxn)[['count']].reset_index()。这可能对某些人有所帮助。
  • 这种方法也有问题。如果user2 值之一为0,则.where(final_df>0) 将自动排除该行。我尝试使用.where(final_df['count'] > 0),但它不起作用。
  • f2 = final_df.set_index(['user1','user2']) f2.where(f2>0).groupby('user2').sum()[['count']].reset_index()
  • final_df[['count']].where(final_df[['count']]>0).groupby(final_df.user2).sum().reset_index()
猜你喜欢
  • 2019-10-18
  • 1970-01-01
  • 2018-11-01
  • 2017-04-06
  • 2018-10-28
  • 1970-01-01
  • 2013-09-01
  • 2017-10-20
  • 2017-10-16
相关资源
最近更新 更多