计算DataFrame每行中系列中项目的出现次数

时间:2014-07-01 17:45:28

标签: python pandas apply

我有pandas.DataFrame看起来像这样。

COL1    COL2    COL3
C1      None    None
C1      C2      None
C1      C1      None
C1      C2      C3

对于此数据帧中的每一行,我想计算每个C1,C2,C3的出现次数,并将此信息作为列附加到此数据帧。例如,第一行具有1个C1,0个C2和0个C3。最终的数据框应如下所示

COL1    COL2    COL3    C1  C2  C3
C1      None    None    1   0   0
C1      C2      None    1   1   0
C1      C1      None    2   0   0
C1      C2      C3      1   1   1

所以,我创建了一个以C1,C2和C3作为值的系列 - 一种最重要的方法是循环遍历DataFrame的行和列,然后通过此系列,并在计数器匹配时递增计数器。但是有一种apply方法能够以紧凑的方式实现这一目标吗?

3 个答案:

答案 0 :(得分:10)

您可以申请value_counts

In [11]: df.apply(pd.Series.value_counts, axis=1)
Out[11]: 
   C1  C2  C3  None
0   1 NaN NaN     2
1   1   1 NaN     1
2   2 NaN NaN     1
3   1   1   1   NaN

所以你可以只用你想要的基本值填充NaN和applend:

In [12]: df.apply(pd.Series.value_counts, axis=1)[['C1', 'C2', 'C3']].fillna(0)
Out[12]: 
   C1  C2  C3
0   1   0   0
1   1   1   0
2   2   0   0
3   1   1   1

注意:直接为DataFrame提供value_counts方法是一个悬而未决的问题(我认为应该由pandas 0.15引入)。

答案 1 :(得分:3)

安迪的回答很明显。

我添加了这个答案,如果C1,C2 ...... Cn列表很大,我们只想查看它们的子集。

dff = df.copy()
dff['C1']=(df == 'C1').T.sum()
dff['C2']=(df == 'C2').T.sum()
dff['C3']=(df == 'C3').T.sum()
dff
  COL1  COL2  COL3  C1  C2  C3
0   C1  None  None   1   0   0
1   C1    C2  None   1   1   0
2   C1    C1  None   2   0   0
3   C1    C2    C3   1   1   1

答案 2 :(得分:0)

通常,对整个数据框使用apply + serise函数会减慢整个过程,其他阅读:Link

df.mask(df.eq('None')).stack().str.get_dummies().sum(level=0)
Out[165]: 
   C1  C2  C3
0   1   0   0
1   1   1   0
2   2   0   0
3   1   1   1

或者您可以使用Counter

from  collections import Counter

pd.DataFrame([ Counter(x) for x in df.values]).drop('None',1)
Out[170]: 
   C1   C2   C3
0   1  NaN  NaN
1   1  1.0  NaN
2   2  NaN  NaN
3   1  1.0  1.0