df.groupby()方法讲解
Posted HTDiiii
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了df.groupby()方法讲解相关的知识,希望对你有一定的参考价值。
df.groupby()方法讲解
分组:根据研究目的,将所有样本点按照一个或多个属性划分为多个组,就是分组。
pandas中,数据表就是DataFrame对象,分组就是groupby方法。将DataFrame中所有行按照一列或多列来划分,分为多个组,列值相同的在同一组,列值不同的在不同组。
分组后,就得到一个groupby对象,代表着已经被分开的各个组。后续所有的动作,比如计数,求平均值等,都是针对这个对象,也就是都是针对各个组。即在每个组组内进行计数,求平均值等。
分组的返回结果
df = pd.DataFrame([['a', 'man', 120, 90],
['b', 'woman', 130, 100],
['a', 'man', 110, 108],
['a', 'woman', 120, 118]], columns=['level', 'gender', 'math','chinese'])
group = df.groupby('gender')
df.groupby() 函数返回的对象是一系列键值对,其中键是分组的字段值,值是该字段值下的数据表。分组的结果是无法直接输出的,print()只能看到该结果的数据类型。可以用循环对分组后的结果进行遍历。
print(group)
# <pandas.core.groupby.generic.DataFrameGroupBy object at 0x11cb60f50>
for key, value in group:
print(key)
print(value)
print("")
man
level gender math chinese
0 a man 120 90
2 a man 110 108
woman
level gender math chinese
1 b woman 130 100
3 a woman 120 118
按一列分组:df.groupby(column)
group = df.groupby('gender') # 按照'gender'列的值来分组,创建一个groupby对象
# group = df.groupby(['gender']) # 等价写法
for key, df in group:
print(key)
print(df)
man
level gender math chinese
0 a man 120 90
2 a man 110 108
woman
level gender math chinese
1 b woman 130 100
3 a woman 120 118
按多列分组:df.groupby([column1, column2])
group = df.groupby(['gender', 'level'])
# 先按照'grade'列的值来分组。每组内,再按'level'列来分组。也返回一个groupby对象
for key, value in group:
print(key)
print(value)
print("")
('man', 'a')
level gender math chinese
0 a man 120 90
2 a man 110 108
('woman', 'a')
level gender math chinese
3 a woman 120 118
('woman', 'b')
level gender math chinese
1 b woman 130 100
查看每组的统计数据:df.groupby(column).describe()
对数据表中的数值列进行统计,给出包括count = 计数,mean = 平均数,std = 方差,min = 最小值,25% = 四分位数,50% = 二分位数,75% = 四分之三分位数,max = 最大值的信息。不会对非数值列统计。
返回的是一个dataframe。
-
查看所有列的统计信息
group = df.groupby(['gender']) df1 = group.describe() # df1 = df.groupby(['gender']).describe() # 等价写法 print(type(df1)) print(df1) <class 'pandas.core.frame.DataFrame'> math chinese \\ count mean std min 25% 50% 75% max count gender man 2.0 115.0 7.071068 110.0 112.5 115.0 117.5 120.0 2.0 woman 2.0 125.0 7.071068 120.0 122.5 125.0 127.5 130.0 2.0 mean std min 25% 50% 75% max gender man 99.0 12.727922 90.0 94.5 99.0 103.5 108.0 woman 109.0 12.727922 100.0 104.5 109.0 113.5 118.0
-
查看指定列的统计信息
group = df.groupby(['gender'])
df1 = group.describe()['math'] # 只看math列的统计信息
print(df1)
count mean std min 25% 50% 75% max
gender
man 2.0 115.0 7.071068 110.0 112.5 115.0 117.5 120.0
woman 2.0 125.0 7.071068 120.0 122.5 125.0 127.5 130.0
-
查看纵向视图
unstack()可以将每列的统计信息垂直排列。
group = df.groupby(['gender'])
df1 = group.describe().unstack()
print(df1)
gender
math count man 2.000000
woman 2.000000
...
max man 120.000000
woman 130.000000
chinese count man 2.000000
woman 2.000000
...
woman 113.500000
max man 108.000000
woman 118.000000
dtype: float64
组内离散列计数:df.groupby(column)[column2].value_counts()
数据表中的列按值是否连续,可以分为连续值列、离散值列。对于离散值列,可以统计其不重复值的个数。对于连续值列,统计不重复值一般没有意义。统计结果是一个Series对象。
group = df.groupby(['gender'])
df1 = group['level'].value_counts() # 统计'level'列的不重复值个数
print(type(df1))
print(df1)
<class 'pandas.core.series.Series'>
gender level
man a 2
woman a 1
b 1py
Name: level, dtype: int64
组内数值列和:df.groupby(column).sum()
group = df.groupby(['gender'])
df1 = group.sum()
print(df1)
math chinese
gender
man 230 198
woman 250 218
组内成员数:df.groupby(column).count()
每组内,按列统计每组的成员数。每列的统计结果是一样的
group = df.groupby(['gender'])
df1 = group.count()
print(df1)
level math chinese
gender
man 2 2 2
woman 2 2 2
组内数值列均值:df.groupby(column).mean()
每组内,统计所有数值列的均值,非数值列无均值。
所有组的均值
group = df.groupby(['gender'])
df1 = group.mean()
print(df1)
math chinese
gender
man 115 99
woman 125 109
单组的均值
group = df.groupby(['gender'])
df1 = group['math'].mean()
print(df1)
gender
man 115
woman 125
Name: math, dtype: int64
组内数值列最大值:df.groupby(column).max()
每组内,统计所有数值列的最大值,非数值列无最大值
统计所有数值列的最大值
group = df.groupby(['gender'])
df1 = group.max()
print(df1)
level math chinese
gender
man a 120 108
woman b 130 118
统计单个数值列的最大值
group = df.groupby(['gender'])
df1 = group['math'].max()
print(df1)
gender
man 120
woman 130
Name: math, dtype: int64
组内应用函数:df.groupby(column1)[column2].apply()
group = df.groupby(['gender'])
df1 = group['math'].apply(np.mean) # 求组内均值
print(df1)
gender
man 115.0
woman 125.0
Name: math, dtype: float64
组内不同列用不同函数:df.groupby(column).agg(column1:func, column2:func,…)
group = df.groupby(['gender'])
df1 = group.agg('math':np.mean, 'chinese':np.std)
print(df1)
math chinese
gender
man 115 12.727922
woman 125 12.727922
什么时候适合使用 df.value_counts() vs df.groupby('...').count()?
【中文标题】什么时候适合使用 df.value_counts() vs df.groupby(\'...\').count()?【英文标题】:When is it appropriate to use df.value_counts() vs df.groupby('...').count()?什么时候适合使用 df.value_counts() vs df.groupby('...').count()? 【发布时间】:2018-05-09 07:45:48 【问题描述】:我听说在 Pandas 中通常有多种方法可以做同样的事情,但我想知道 –
如果我尝试按特定列中的值对数据进行分组并计算具有该值的项目数,那么何时使用 df.groupby('colA').count()
有意义,何时使用 df['colA'].value_counts()
有意义?
【问题讨论】:
【参考方案1】:简单地说:.value_counts()
返回一个包含 DataFrame 中唯一行计数的系列,这意味着它计算特定行中的各个值并报告有多少值在柱子:
想象一下我们有一个如下的数据框:
df = pd.DataFrame('first_name': ['John', 'Anne', 'John', 'Beth'],
'middle_name': ['Smith', pd.NA, pd.NA, 'Louise'])
first_name middle_name
0 John Smith
1 Anne <NA>
2 John <NA>
3 Beth Louise
然后我们对其应用 value_counts:
df.value_counts()
first_name middle_name
Beth Louise 1
John Smith 1
dtype: int64
如您所见,它没有计算具有 NA 值的行。
但是count()
计算每列或每行的非 NA 单元格。
在我们的示例中:
df.count()
first_name 4
middle_name 2
dtype: int64
【讨论】:
【参考方案2】:Groupby
和value_counts
是完全不同的功能。您不能对数据框执行 value_counts。
Value Counts
仅限于单个列或系列,其唯一目的是返回值的频率系列
Groupby
返回一个对象,以便对其执行统计计算。因此,当您执行 df.groupby(col).count()
时,它将返回相对于 groupby 中的 specific columns
列中存在的真实值的数量。
什么时候应该使用value_counts
,什么时候应该使用groupby.count
:
举个例子吧
df = pd.DataFrame('id': [1, 2, 3, 4, 2, 2, 4], 'color': ["r","r","b","b","g","g","r"], 'size': [1,2,1,2,1,3,4])
分组计数:
df.groupby('color').count()
id size
color
b 2 2
g 2 2
r 3 3
Groupby 计数通常用于获取值的有效数量 出现在所有列中
with reference to
或with respect to
一个 或更多列指定。所以不会排除数字(nan)。
要使用 groupby 查找频率,您需要像 @jez 那样对指定的列本身进行聚合。 (也许可以避免这种情况并让开发人员轻松实现 value_counts )。
价值计数:
df['color'].value_counts()
r 3
g 2
b 2
Name: color, dtype: int64
值计数通常用于查找值的频率 出现在一个特定的列中。
总结:
.groupby(col).count()
应在您想要查找与指定col
相关的列中有效值出现的频率时使用。
.value_counts()
应该用于查找序列的频率。
【讨论】:
【参考方案3】:有区别value_counts
返回:
生成的对象将按降序排列,因此第一个元素是最常出现的元素。
但count
不是,它按index
(由groupby('col')
中的列创建)对输出进行排序。
df.groupby('colA').count()
用于通过函数count.
聚合df
的所有列,因此它计算的值不包括NaN
s。
所以如果需要count
只需要一列:
df.groupby('colA')['colA'].count()
示例:
df = pd.DataFrame('colB':list('abcdefg'),
'colC':[1,3,5,7,np.nan,np.nan,4],
'colD':[np.nan,3,6,9,2,4,np.nan],
'colA':['c','c','b','a',np.nan,'b','b'])
print (df)
colA colB colC colD
0 c a 1.0 NaN
1 c b 3.0 3.0
2 b c 5.0 6.0
3 a d 7.0 9.0
4 NaN e NaN 2.0
5 b f NaN 4.0
6 b g 4.0 NaN
print (df['colA'].value_counts())
b 3
c 2
a 1
Name: colA, dtype: int64
print (df.groupby('colA').count())
colB colC colD
colA
a 1 1 1
b 3 2 2
c 2 2 1
print (df.groupby('colA')['colA'].count())
colA
a 1
b 3
c 2
Name: colA, dtype: int64
【讨论】:
以上是关于df.groupby()方法讲解的主要内容,如果未能解决你的问题,请参考以下文章
Pandas 的 [df.groupby(...)['col_name'].shift(1)] 的 SQL 等效项
Pandas:df.groupby(x, y).apply() 跨多个列参数错误
df.groupby('id').resample('D').last() 在 Pandas 中的 Pyspark 等效项