熊猫:爆炸数组元素和组?

时间:2018-09-17 16:48:05

标签: pandas

我正在Pandas 0.23中工作,我有一个数组列和一个布尔列。我想按布尔值和数组中的每个单独元素分组,以找到每个元素为真和假的计数。

示例数据:

a = pd.DataFrame([
  {'vals': ['a,b,c'], 'succeeded': True},
  {'vals': ['a,b'], 'succeeded': False},
  {'vals': ['c'], 'succeeded': True},
  {'vals': ['b,d'], 'succeeded': False},
])

所需的输出:

      succeeded_t     succeeded_f
a     1               1
b     1               2
c     2               0
d     0               1

执行此操作的最佳方法是什么?我是否需要先将数组元素“分解”为行,然后进行分组?

2 个答案:

答案 0 :(得分:2)

也许您可以一口气做到这一点,但只需将其分为两组,并在每个子集上使用str.get_dummies,然后将结果连接起来

import pandas as pd

pd.concat([a[a.succeeded].vals.str.get_dummies(sep=',').sum().to_frame('succeeded_t'),
           a[~a.succeeded].vals.str.get_dummies(sep=',').sum().to_frame('succeeded_f')], 
          axis=1, sort=True).fillna(0)

输出:

   succeeded_t  succeeded_f
a          1.0          1.0
b          1.0          2.0
c          2.0          0.0
d          0.0          1.0

或者

如果您的输出中有很多列您不想手动连接:

(a.set_index('succeeded')
  .vals.str.get_dummies(sep=',')
  .groupby(level=0).sum().T
  .rename_axis(None, axis=1))

输出:

   False  True 
a      1      1
b      2      1
c      0      2
d      1      0

答案 1 :(得分:2)

您可能需要先平铺列表,然后使用crosstab,但您的列表不是list,它是一个带字符串的项目列表,您需要先将其拆分

a.vals=a.vals.map(lambda x : x[0].split(','))
newdf=pd.DataFrame({'succeeded':a['succeeded'].reindex(a.index.repeat(a.vals.str.len())),
                    'vals':np.concatenate(a['vals'].values)})
pd.crosstab(newdf['vals'],newdf['succeeded'])
Out[457]: 
succeeded  False  True 
vals                   
a              1      1
b              2      1
c              0      2
d              1      0