pandas5 数据分组与聚合

5.数据分组与聚合

数据分组

1.groupby方法:DataFrame.groupby(by=None, axis=0, level=None, as_index=True, sort=True, group_keys=True, squeeze=False)

参数名称参数说明
by可以传入函数、字典、Series等,用于分组的依据条件
axis0或者1,表示操作的轴方向默认按列操作,取1按行操作
level接收int或者索引名,代表标签所在的级别,默认None
as_index接收boolean,表示聚合后的聚合标签是否以DataFrame的索引输出,默认True
sort接收boolean,对分组依据和分组标签排序,默认True
group_keys接收boolean,表示是否显示分组标签的名称,默认True
squeeze接收Boolean,表示是否在允许情况下对数据进行降维操作,默认False

参数by,如果传入函数,则对索引进行计算并分组;如果传入字典或者Series,则字典或者Series的值作为分组依据;如果传入Numpy数组,则数据元素作为分组依据;如果传入字符串或者字符串列表,则用这些字符串所代表的字段作为分组依据。

数据分组之后返回的是一个groupby对象,可以调用该对象的方法如size返回一个含有分组大小的Series。

#取df['data1']这一列数据并按df['key1']这一列的数据来分组  分完之后a:3 ,b:2
import numpy as np
import pandas as pd
##groupby()
df = pd.DataFrame({
    'key1':['a','a','b','b','a'],
    'key2':[1,0,1,1,0],
    'data1':np.random.randn(5),
    'data2':np.random.randn(5)
})
print(df)
grouped = df['data1'].groupby(df['key1'])
print(grouped.size())
print(grouped.mean())
  key1  key2     data1     data2
0    a     1  0.410518  0.204681
1    a     0 -0.558132 -0.008501
2    b     1 -0.008334 -1.935630
3    b     1 -0.481743  0.775196
4    a     0  0.597605  0.561882
key1
a    3
b    2
Name: data1, dtype: int64
key1
a    0.149997
b   -0.245038
Name: data1, dtype: float64

2.按列名分组:DataFrame数据的列索引名可以作为分组键,但是用于分组的对象必须是DataFrame本身。不然会报错找不到索引名称。

#按列索引名称分组
grouped1 = df.groupby('key1').size()
grouped2 = df.groupby('key1').mean()
print(grouped1)
grouped2
key1
a    3
b    2
dtype: int64

key2	data1	data2
key1			
a	0.333333	0.149997	0.252688
b	1.000000	-0.245038	-0.580217

3.按列表或元组分组:分组键还可以是和DataFrame行数相等的列表或者元组,相当于把列表或者元组当成DataFrame的一列,然后分组。

##所给的按列表或元组
w = ['w','w','y','w','y']
df.groupby(w).sum()

key2	data1	data2
w	2	-0.629356	0.971377
y	1	0.589272	-1.373748

4.按字典分组:如果原始的DataFrame中分组信息难以确定或不存在,则可以通过字典结构定义一个分组信息。

#定义一个字典来分组  分组信息:不区分大小写来分组
df = pd.DataFrame(np.random.normal(size=(6,5)), index=['a','b','A','B','c','C'])
print(df)
dic = {
    "a":'one',
    "b":'two',
    "c":'three',
    "A":'one',
    "B":'two',
    "C":'three'
}
x = df.groupby(dic)
print(x.sum())

          0         1         2         3         4
a -0.422562  1.962075 -0.489384 -1.304302 -1.109478
b  1.134703 -0.358548 -1.373025  0.851012 -0.302279
A -0.196233 -0.192463  0.286070  0.872550 -0.835654
B -0.038677 -0.130829 -0.599642 -0.201865 -1.849057
c -0.033203 -0.512046 -0.414564  0.516591  1.191699
C -1.145768  0.176744 -0.160164  1.435075 -0.124890
              0         1         2         3         4
one   -0.618795  1.769613 -0.203314 -0.431753 -1.945131
three -1.178971 -0.335301 -0.574728  1.951666  1.066808
two    1.096026 -0.489377 -1.972667  0.649148 -2.151336

5.按函数分组:类似于字典,通过映射关系来进行分组

#函数
def judge(x):
    if x>=0:
        return 'a'
    else:
        return 'b'
df = pd.DataFrame(np.random.randn(4,4))
print(df)
print(df[3].groupby(df[3].map(judge)).sum())
          0         1         2         3
0  0.714710 -1.180971  0.177371  1.257526
1 -0.465390  0.822470  1.767948  0.740839
2  0.194928  0.658354 -0.053870 -0.657892
3  1.001120 -1.195080  1.122340 -1.813876

a    1.998365
b   -2.471768
Name: 3, dtype: float64
数据聚合:对分组后的数据进行计算,产生标量值的数据转换过程。

1.聚合函数:在聚合运算中,空值不参加计算

函数使用说明
count计数
sum求和
mean平均值
median中位数
std、var无偏标准差和方差
min、max最小、最大值
prod求积
first、last第一个和最后一个值

2.agg方法实现聚合数据:支持对每个分组应用某个函数。能直接对DataFrame进行函数应用操作。

#agg
## 使用agg求出当前数据对应的统计量
data = pd.read_excel('D:\python\数据分析与可视化\第四章:pandas统计分析基础\data\\testdata.xls')
print(data.head())
print('求当前数据的各项统计量:\n',data[['淋巴细胞计数','白细胞计数']].agg([np.sum, np.mean]))
## 使用agg函数分别求各字段不同的统计量
print('求个字段的不同统计量:\n',data.agg({'淋巴细胞计数':np.mean, '白细胞计数':np.std}))

## 计算不同字段不同数目的统计量
print('计算不同字段不同数目的统计量:\n',data.agg({'淋巴细胞计数':np.mean, '白细胞计数':[np.std, np.mean]}))

## 统计不同性别人群的血小板计数的平均值
print('统计不同性别人群的血小板计数:\n',data.groupby('性别')['血小板计数'].agg(np.mean))
## 返回的数据不希望以分组键为索引  as_index=False实现
print('统计不同性别人群的血小板计数:\n',data.groupby('性别',as_index=False)['血小板计数'].agg(np.mean))

   序号  性别            身份证号 是否吸烟 是否饮酒 开始从事某工作年份  体检年份  淋巴细胞计数  白细胞计数  细胞其它值  \
0    1****1982080000    否    否     20092017     2.4    8.5    NaN   
1    2****1984110000    否    否     20152017     1.8    5.8    NaN   
2    3****1983060000    否    否     20132017     2.0    5.6    NaN   
3    4****1985040000    否    否     20142017     2.5    6.6    NaN   
4    5****1986040000    否    否     20142017     1.3    5.2    NaN   

   血小板计数  
0  248.0  
1  300.0  
2  195.0  
3  252.0  
4  169.0  
求当前数据的各项统计量:
            淋巴细胞计数        白细胞计数
sum   4280.270000  6868.008100
mean     3.849164     6.176266
求个字段的不同统计量:
 淋巴细胞计数     3.849164
白细胞计数     12.043418
dtype: float64
计算不同字段不同数目的统计量:
         淋巴细胞计数      白细胞计数
mean  3.849164   6.176266
std        NaN  12.043418
统计不同性别人群的血小板计数:
 性别
女    212.687636194.727417
Name: 血小板计数, dtype: float64
统计不同性别人群的血小板计数:
   性别       血小板计数
0212.687636
1194.727417

分组运算:包含聚合运算,聚合运算是数据转换的特例。

1.transform方法:将运算分不到每一行

# 分组运算
## transform  运算分布到每一行
data.groupby('性别')['血小板计数'].transform('mean').sample(5)


915     194.727417
1039    194.727417
1062    194.727417
95      194.727417
416     212.687636
Name: 血小板计数, dtype: float64

2.apply方法:类似于agg方法,可以将函数应用于每一列

## apply  函数应用到每列  axis=1  应用到每行
data.groupby(['性别','是否吸烟'])['血小板计数'].apply(np.mean)


性别  是否吸烟
女   否       212.133188297.333333
男   否       194.236749195.210175
重要技巧:

groupby之后直接.reset_index()可以得到一个没有多级索引的DataFram,之后可以通过df.rename({‘old_col1’:‘new_col1’,‘old_col2’:‘new_col2’,…})重命名

df1= df.groupby([‘date’])[‘price’].agg({‘sum’,‘count’}).reset_index()

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值