在pandas中汇总分组值计数的最佳方法
这是我的数据表:
id b1 b2 b3 c
-------------
1 aa bb cc a
2 ac bc cd b
3 ac ad cc a
4 ad cd ae b
b1、b2 和 b3 这三列的意思是一样的。现在我想根据列 c
来分组数据,并计算 b1、b2 和 b3 中单词的出现次数。以下是我的代码:
grp = df.groupby('c')
vc1 = grp['b1'].value_counts()
vc2 = grp['b2'].value_counts()
vc3 = grp['b3'].value_counts()
sum([vc1, vc2, vc3])
但是结果中出现了很多 NA(缺失值)。我该怎么设置默认值为 0 呢?
2 个回答
1
根据pandas库中的一些函数,比如groupby
、get_group
、value_counts
和add
,我提出了以下建议。
import pandas as pd
# Creation of the dataframe example
df = pd.DataFrame.from_dict({'b1':['aa','ac','ac','ad'],\
'b2':['bb','bc','ad','cd'],\
'b3':['cc','cd','cc','ae'],\
'c' :['a','b','a','b']})
# Group data wrt column c
grp = df.groupby('c')
# Create empty dataframe that will hold results
dfc = pd.DataFrame()
# Iterate over all groups
for g in grp.groups:
# Select the current group
cg = grp.get_group(g)
# Iterate over all columns to be counted
for c in ['b1','b2','b3']:
# Perform all value_counts and
# add result to the correct column in result dataframe
dfc = dfc.add(pd.DataFrame({g:cg[c].value_counts()}),fill_value=0)
# Replace all Nan with 0
dfc.fillna(0, inplace = True)
结果会像这样
a b
aa 1 0
ac 1 1
ad 1 1
ae 0 1
bb 1 0
bc 0 1
cc 2 0
cd 0 2
2
这里有一个相当高效的方法。
首先,按照 'c' 这一列进行分组,然后考虑你想要传递给 apply
的所有其他列,除了 'c' 这一列(这就是 df.columns-['c']
的作用,因为通常情况下,分组的那一列也会被传递给 apply)。
接着,简单地对所有数据使用 value_counts
(ravel
会把二维的数据变成一维的),因为你最终是想要总数。
In [92]: df.groupby('c')[df.columns - ['c']].apply(lambda x: x.unstack().value_counts())
Out[92]:
c
a cc 2
bb 1
ad 1
ac 1
aa 1
b cd 2
ad 1
ae 1
ac 1
bc 1
dtype: int64
如果你想要以列的形式展示结果
In [97]: df.groupby('c')[df.columns - ['c']].apply(lambda x: x.unstack().value_counts()).unstack().T.fillna(0)
Out[97]:
c a b
aa 1 0
ac 1 1
ad 1 1
ae 0 1
bb 1 0
bc 0 1
cc 2 0
cd 0 2