我正在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
执行此操作的最佳方法是什么?我是否需要先将数组元素“分解”为行,然后进行分组?
答案 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