将价值应用于 Pandas 枢轴级别的所有成员

Posted

技术标签:

【中文标题】将价值应用于 Pandas 枢轴级别的所有成员【英文标题】:Applying value to all members in Pandas pivot level 【发布时间】:2017-12-19 00:50:19 【问题描述】:

我有一个简单的 Pandas DataFrame t,如下所示:

  > print t

    group_id    item_id  traitx
  0   groupA  000001-00    True
  1   groupA  000002-00    True
  2   groupA  000003-00   False
  3   groupB  000001-00    True
  4   groupC  000002-00    True
  5   groupC  000004-00    True

  > t.pivot_table(index=['groupid', 'item_id'])

                      traitx
  group_id item_id          
  groupA   000001-00    True
           000002-00    True
           000003-00   False
  groupB   000001-00    True
  groupC   000001-00    True
           000002-00    True

目标:我需要计算属于group_id 的总行数,其traitx 的值都是True

我解决这个问题的想法是以某种方式添加一个列,以显示每一行的整个组是否为 True,例如

    group_id    item_id  traitx  group_traitx
  0   groupA  000001-00    True         False
  1   groupA  000002-00    True         False
  2   groupA  000003-00   False         False
  3   groupB  000001-00    True         True
  4   groupC  000002-00    True         True
  5   groupC  000004-00    True         True

然后只计算group_traitx 的总和。

我可以用以下公式计算group_traitx

> print t.groupby('group_id')['traitx'].all()

group_id
groupA    False
groupB     True
groupC     True
Name: traitx, dtype: bool

但是,我不知道如何将结果“涂抹”回原始 DataFrame 中的 group_traitx 列。

免责声明 - 我昨天才开始使用 Pandas,所以这可能不是实现我最初目标的最佳方式。

【问题讨论】:

【参考方案1】:

你可以使用transform:

df= t.pivot_table(index=['group_id', 'item_id'])
df['group_traitx'] = df.groupby(level=0)['traitx'].transform('all')
print (df)
                    traitx  group_traitx
group_id item_id                        
groupA   000001-00    True         False
         000002-00    True         False
         000003-00   False         False
groupB   000001-00    True          True
groupC   000002-00    True          True
         000004-00    True          True

print (df['group_traitx'].sum())
3

不需要新列:

print (df.groupby(level=0)['traitx'].transform('all').sum())
3

如果只需要所有True 组使用filter:

df= t.pivot_table(index=['group_id', 'item_id'])
print (df.groupby(level=0)['traitx'].filter('all'))

group_id  item_id  
groupB    000001-00    True
groupC    000002-00    True
          000004-00    True
Name: traitx, dtype: bool

print (df.groupby(level=0)['traitx'].filter('all').sum())
3

编辑:

如果在 group_iditem_id 对中重复:

#added duplicates
print (t)
  group_id    item_id  traitx
0   groupA  000001-00    True
1   groupA  000001-00    True
2   groupA  000001-00   False
3   groupB  000001-00    True
4   groupC  000002-00    True
5   groupC  000004-00    True

#pivot_table is not necessary for new column of original df
t['group_traitx'] = t.groupby(['group_id', 'item_id'])['traitx'].transform('all')
print (t)
  group_id    item_id  traitx  group_traitx
0   groupA  000001-00    True         False
1   groupA  000001-00    True         False
2   groupA  000001-00   False         False
3   groupB  000001-00    True          True
4   groupC  000002-00    True          True
5   groupC  000004-00    True          True

如果需要使用聚合 df(唯一对 group_iditem_id): pivot_table使用默认聚合函数mean,但需要all聚合:

print (t.pivot_table(index=['group_id', 'item_id']))
                      traitx
group_id item_id            
groupA   000001-00  0.666667
groupB   000001-00  1.000000
groupC   000002-00  1.000000
         000004-00  1.000000

df = t.pivot_table(index=['group_id', 'item_id'], aggfunc='all')
df['group_traitx'] = df.groupby(level=0)['traitx'].transform('all')
print (df)
                    traitx  group_traitx
group_id item_id                        
groupA   000001-00   False         False
groupB   000001-00    True          True
groupC   000002-00    True          True
         000004-00    True          True

【讨论】:

太棒了!我不得不分组(级别= 1),但除此之外,这完美无缺。 transform() 的文档有点不透明。您对我在哪里可以看到要传入的可接受函数名称列表或任何综合示例有任何指示吗? 你可以使用很多功能 - 见list。

以上是关于将价值应用于 Pandas 枢轴级别的所有成员的主要内容,如果未能解决你的问题,请参考以下文章

如何将计算成员添加到级别的所有成员?

如何通过不同级别的枢轴聚合然后在pyspark中进行内部连接?

下采样到季度级别并在 Pandas 中获取季度结束日期值

Pandas 从多索引级别获取所有值

Pandas MultiIndex(超过 2 个级别)DataFrame 到嵌套 Dict/JSON

Pandas:将多索引级别作为系列