Groupby值在dataframe pandas上计数

2024-04-27 19:53:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下数据框:

df = pd.DataFrame([
    (1, 1, 'term1'),
    (1, 2, 'term2'),
    (1, 1, 'term1'),
    (1, 1, 'term2'),
    (2, 2, 'term3'),
    (2, 3, 'term1'),
    (2, 2, 'term1')
], columns=['id', 'group', 'term'])

我想按idgroup对它进行分组,并计算这个id组对的每个项的数目。

最后我会得到这样的结果:

enter image description here

我可以通过使用df.iterrows()循环遍历所有行并创建一个新的数据帧来实现我想要的目标,但这显然是低效的。(如果有帮助的话,我事先知道所有条款的清单,其中大约有10个)。

看起来我必须先按分组,然后再计算值,所以我尝试用df.groupby(['id', 'group']).value_counts()进行分组,但该方法不起作用,因为value_counts操作的是group by系列,而不是数据帧。

不管怎样,我不需要循环就可以做到这一点?


Tags: columns数据term1iddataframedfvaluegroup
3条回答

我用groupbysize

df.groupby(['id', 'group', 'term']).size().unstack(fill_value=0)

enter image description here


时机

enter image description here

1000000行

df = pd.DataFrame(dict(id=np.random.choice(100, 1000000),
                       group=np.random.choice(20, 1000000),
                       term=np.random.choice(10, 1000000)))

enter image description here

使用pivot_table()方法:

In [22]: df.pivot_table(index=['id','group'], columns='term', aggfunc='size', fill_value=0)
Out[22]:
term      term1  term2  term3
id group
1  1          2      1      0
   2          0      1      0
2  2          1      0      1
   3          1      0      0

针对700K行DF的计时:

In [24]: df = pd.concat([df] * 10**5, ignore_index=True)

In [25]: df.shape
Out[25]: (700000, 3)

In [3]: %timeit df.groupby(['id', 'group', 'term'])['term'].size().unstack(fill_value=0)
1 loop, best of 3: 226 ms per loop

In [4]: %timeit df.pivot_table(index=['id','group'], columns='term', aggfunc='size', fill_value=0)
1 loop, best of 3: 236 ms per loop

In [5]: %timeit pd.crosstab([df.id, df.group], df.term)
1 loop, best of 3: 355 ms per loop

In [6]: %timeit df.groupby(['id','group','term'])['term'].size().unstack().fillna(0).astype(int)
1 loop, best of 3: 232 ms per loop

In [7]: %timeit df.groupby(['id', 'group', 'term']).size().unstack(fill_value=0)
1 loop, best of 3: 231 ms per loop

针对7M排DF的计时:

In [9]: df = pd.concat([df] * 10, ignore_index=True)

In [10]: df.shape
Out[10]: (7000000, 3)

In [11]: %timeit df.groupby(['id', 'group', 'term'])['term'].size().unstack(fill_value=0)
1 loop, best of 3: 2.27 s per loop

In [12]: %timeit df.pivot_table(index=['id','group'], columns='term', aggfunc='size', fill_value=0)
1 loop, best of 3: 2.3 s per loop

In [13]: %timeit pd.crosstab([df.id, df.group], df.term)
1 loop, best of 3: 3.37 s per loop

In [14]: %timeit df.groupby(['id','group','term'])['term'].size().unstack().fillna(0).astype(int)
1 loop, best of 3: 2.28 s per loop

In [15]: %timeit df.groupby(['id', 'group', 'term']).size().unstack(fill_value=0)
1 loop, best of 3: 1.89 s per loop

与其记住冗长的解决方案,不如看看熊猫为您构建的解决方案:

df.groupby(['id', 'group', 'term']).count()

相关问题 更多 >