Get statistics for each group (such as count, mean, etc) using pandas GroupBy?
我有一个数据框
1 | df['col1','col2','col3','col4'].groupby(['col1','col2']).mean() |
以上面的方式,我几乎得到了我需要的表(数据框)。 缺少的是包含每个组中行数的附加列。 换句话说,我有意思,但我也想知道有多少数字被用来获得这些手段。 例如,在第一组中有8个值,在第二组中有10个,依此类推。
简而言之:如何获取数据帧的分组统计信息?
快速回答:
获取每组行数的最简单方法是调用
1 | df.groupby(['col1','col2']).size() |
通常您希望此结果为
1 | df.groupby(['col1', 'col2']).size().reset_index(name='counts') |
如果您想了解如何计算每个组的行数和其他统计数据,请继续阅读下面的内容。
详细示例:
请考虑以下示例数据帧:
1 2 3 4 5 6 7 8 9 10 11 12 13 | In [2]: df Out[2]: col1 col2 col3 col4 col5 col6 0 A B 0.20 -0.61 -0.49 1.49 1 A B -1.53 -1.01 -0.39 1.82 2 A B -0.44 0.27 0.72 0.11 3 A B 0.28 -1.32 0.38 0.18 4 C D 0.12 0.59 0.81 0.66 5 C D -0.13 -1.65 -1.64 0.50 6 C D -1.42 -0.11 -0.18 -0.44 7 E F -0.00 1.42 -0.26 1.17 8 E F 0.91 -0.47 1.35 -0.34 9 G H 1.48 -0.63 -1.14 0.17 |
首先让我们使用
1 2 3 4 5 6 7 8 | In [3]: df.groupby(['col1', 'col2']).size() Out[3]: col1 col2 A B 4 C D 3 E F 2 G H 1 dtype: int64 |
然后让我们使用
1 2 3 4 5 6 7 | In [4]: df.groupby(['col1', 'col2']).size().reset_index(name='counts') Out[4]: col1 col2 counts 0 A B 4 1 C D 3 2 E F 2 3 G H 1 |
包括更多统计数据的结果
如果要计算分组数据的统计信息,通常如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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 A B -0.810 -1.32 4 -0.372500 4 C D -0.110 -1.65 3 -0.476667 3 E F 0.475 -0.47 2 0.455000 2 G H -0.630 -0.63 1 1.480000 1 |
由于嵌套列标签,上面的结果有点烦人,也因为行数是基于每列的。
为了获得对输出的更多控制,我通常将统计数据拆分为单个聚合,然后使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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 A B 4 -0.372500 -0.810 -1.32 1 C D 3 -0.476667 -0.110 -1.65 2 E F 2 0.455000 0.475 -0.47 3 G H 1 1.480000 -0.630 -0.63 |
脚注
用于生成测试数据的代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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) ...: |
免责声明:
如果您聚合的某些列具有空值,那么您确实希望将组行计数视为每列的独立聚合。否则,您可能会被误导为实际使用了多少记录来计算平均值,因为大熊猫会在平均计算中丢弃
在
1 | df[['col1', 'col2', 'col3', 'col4']].groupby(['col1', 'col2']).agg(['mean', 'count']) |
统治所有的一个功能:
每组返回
1 | df.groupby(['col1', 'col2'])['col3', 'col4'].describe() |
1 2 3 4 5 6 7 8 | # Setup np.random.seed(0) df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], 'B' : ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], 'C' : np.random.randn(8), 'D' : np.random.randn(8)}) |
1 2 3 4 5 6 7 8 9 10 11 12 13 | from IPython.display import display with pd.option_context('precision', 2): display(df.groupby(['A', 'B'])['C'].describe()) count mean std min 25% 50% 75% max A B bar one 1.0 0.40 NaN 0.40 0.40 0.40 0.40 0.40 three 1.0 2.24 NaN 2.24 2.24 2.24 2.24 2.24 two 1.0 -0.98 NaN -0.98 -0.98 -0.98 -0.98 -0.98 foo one 2.0 1.36 0.58 0.95 1.15 1.36 1.56 1.76 three 1.0 -0.15 NaN -0.15 -0.15 -0.15 -0.15 -0.15 two 2.0 1.42 0.63 0.98 1.20 1.42 1.65 1.87 |
要获取具体的统计数据,只需选择它们,
1 2 3 4 5 6 7 8 9 10 | df.groupby(['A', 'B'])['C'].describe()[['count', 'mean']] count mean A B bar one 1.0 0.400157 three 1.0 2.240893 two 1.0 -0.977278 foo one 2.0 1.357070 three 1.0 -0.151357 two 2.0 1.423148 |
您还可以获得字符串数据的不同统计信息这是一个例子,
1 | df2 = df.assign(D=list('aaabbccc')).sample(n=100, replace=True) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | with pd.option_context('precision', 2): display(df2.groupby(['A', 'B']) .describe(include='all') .dropna(how='all', axis=1)) C D count mean std min 25% 50% 75% max count unique top freq A B bar one 14.0 0.40 5.76e-17 0.40 0.40 0.40 0.40 0.40 14 1 a 14 three 14.0 2.24 4.61e-16 2.24 2.24 2.24 2.24 2.24 14 1 b 14 two 9.0 -0.98 0.00e+00 -0.98 -0.98 -0.98 -0.98 -0.98 9 1 c 9 foo one 22.0 1.43 4.10e-01 0.95 0.95 1.76 1.76 1.76 22 2 a 13 three 15.0 -0.15 0.00e+00 -0.15 -0.15 -0.15 -0.15 -0.15 15 1 c 15 two 26.0 1.49 4.48e-01 0.98 0.98 1.87 1.87 1.87 26 2 b 15 |
有关更多信息,请参阅文档。
我们可以通过使用groupby和count轻松完成。但是,我们应该记得使用reset_index()。
1 2 | df[['col1','col2','col3','col4']].groupby(['col1','col2']).count().\ reset_index() |
创建一个组对象并调用如下示例的方法:
1 2 3 4 5 | grp = df.groupby(['col1', 'col2', 'col3']) grp.max() grp.mean() grp.describe() |