如何统计pandas组中每个对象的行数?
我有一个dataframedf
,我用它的几个列groupby
:
df['col1','col2','col3','col4'].groupby(['col1','col2']).mean()
在上面的方式,我几乎得到我需要的表(数据框)。 缺less的是一个包含每个组中行数的附加列。 换句话说,我有这个意思,但我也想知道有多less个数字被用来获得这些手段。 例如,在第一组中有8个值,在第二个中有10个,依此类推。
在groupby
对象上, agg
函数可以通过列表来一次性应用多个聚合方法 。 这应该给你你需要的结果:
df[['col1', 'col2', 'col3', 'col4']].groupby(['col1', 'col2']).agg(['mean', 'count'])
快速回答:
最简单的方法是调用.size()
,它返回一个pandas.Series
:
df.groupby(['col1','col2']).size()
通常你需要把结果作为一个pandas.DataFrame
来代替,所以你可以这样做:
df.groupby(['col1', 'col2']).size().reset_index(name='counts')
详细例子:
考虑下面的示例数据框:
In [2]: df Out[2]: col1 col2 col3 col4 col5 col6 0 AB 0.20 -0.61 -0.49 1.49 1 AB -1.53 -1.01 -0.39 1.82 2 AB -0.44 0.27 0.72 0.11 3 AB 0.28 -1.32 0.38 0.18 4 CD 0.12 0.59 0.81 0.66 5 CD -0.13 -1.65 -1.64 0.50 6 CD -1.42 -0.11 -0.18 -0.44 7 EF -0.00 1.42 -0.26 1.17 8 EF 0.91 -0.47 1.35 -0.34 9 GH 1.48 -0.63 -1.14 0.17
首先让我们使用.size()
来获取行数:
In [3]: df.groupby(['col1', 'col2']).size() Out[3]: col1 col2 AB 4 CD 3 EF 2 GH 1 dtype: int64
然后让我们使用.size().reset_index(name='counts')
来获得行数:
In [4]: df.groupby(['col1', 'col2']).size().reset_index(name='counts') Out[4]: col1 col2 counts 0 AB 4 1 CD 3 2 EF 2 3 GH 1
包括更多统计的结果
当你想计算分组数据的统计数据时,通常看起来像这样:
In [5]: (df ...: .groupby(['col1', 'col2']) ...: .agg({ ...: 'col3': ['mean', 'count'], ...: 'col4': ['median', 'min', 'count'] ...: })) Out[5]: col4 col3 median min count mean count col1 col2 AB -0.810 -1.32 4 -0.372500 4 CD -0.110 -1.65 3 -0.476667 3 EF 0.475 -0.47 2 0.455000 2 GH -0.630 -0.63 1 1.480000 1
上面的结果是有点讨厌的,因为嵌套的列标签,也因为行计数是在每列的基础上。
为了获得对输出的更多控制权,我通常会将统计信息拆分成单独的聚合,然后使用join
进行组合。 它看起来像这样:
In [6]: gb = df.groupby(['col1', 'col2']) ...: counts = gb.size().to_frame(name='counts') ...: (counts ...: .join(gb.agg({'col3': 'mean'}).rename(columns={'col3': 'col3_mean'})) ...: .join(gb.agg({'col4': 'median'}).rename(columns={'col4': 'col4_median'})) ...: .join(gb.agg({'col4': 'min'}).rename(columns={'col4': 'col4_min'})) ...: .reset_index() ...: ) ...: Out[6]: col1 col2 counts col3_mean col4_median col4_min 0 AB 4 -0.372500 -0.810 -1.32 1 CD 3 -0.476667 -0.110 -1.65 2 EF 2 0.455000 0.475 -0.47 3 GH 1 1.480000 -0.630 -0.63
脚注
用于生成testing数据的代码如下所示:
In [1]: import numpy as np ...: import pandas as pd ...: ...: keys = np.array([ ...: ['A', 'B'], ...: ['A', 'B'], ...: ['A', 'B'], ...: ['A', 'B'], ...: ['C', 'D'], ...: ['C', 'D'], ...: ['C', 'D'], ...: ['E', 'F'], ...: ['E', 'F'], ...: ['G', 'H'] ...: ]) ...: ...: df = pd.DataFrame( ...: np.hstack([keys,np.random.randn(10,4).round(2)]), ...: columns = ['col1', 'col2', 'col3', 'col4', 'col5', 'col6'] ...: ) ...: ...: df[['col3', 'col4', 'col5', 'col6']] = \ ...: df[['col3', 'col4', 'col5', 'col6']].astype(float) ...:
免责声明:
如果您正在聚合的某些列具有空值,那么您确实希望将组行计数视为每列的独立聚合。 否则,你可能会被误导,实际上有多lesslogging被用来计算像平均值这样的东西,因为大pandas会在平均计算中放弃NaN
条目而不告诉你。