分组与分箱
学习目标
- 知道Pandas分组聚合的使用方法
- 知道Pandas数据离散化分箱操作的使用方法
1 分组对象DataFrameGroupBy
1.1 df.groupby分组函数返回分组对象
-
导入pandas包, 加载链家租房数据集
import pandas as pd # 加载数据集, 查看前5条数据 df = pd.read_csv('../data/LJdata.csv') print(df.head()) # 输出结果如下 区域 地址 户型 面积 价格 朝向 更新时间 看房人数 0 燕莎租房 新源街 2室1厅 50 5800 南 2017.07.21 26 1 望京租房 澳洲康都 2室1厅 79 7800 东 2017.07.23 33 2 广安门租房 远见名苑 2室1厅 86 8000 东 2017.07.20 34 3 天通苑租房 天通苑北一区 2室1厅 103 5300 东南 2017.07.25 30 4 团结湖租房 团结湖北口 2室1厅 63 6400 南 2017.07.26 30
-
基于一列进行分组
# 基于区域分组 gs = df.groupby(by=['区域']) print(gs) # 获取每组的地址列 print(gs['地址']) # 输出结果如下 <pandas.core.groupby.generic.DataFrameGroupBy object at 0x7fb54301bb50> <pandas.core.groupby.generic.SeriesGroupBy object at 0x7fb55753ec10>
-
基于多列进行分组
# 基于不同区域, 不同户型分组 gs = df.groupby(by=['区域', '户型']) print(gs) # 输出结果如下 <pandas.core.groupby.generic.DataFrameGroupBy object at 0x7fb956bdac10>
-
返回的分组对象可以直接使用,或选择一列做聚合、转换、过滤操作;比如要计算不同区域、不同户型的平均租金
res = df.groupby(by=['区域', '户型'])['价格'].mean() print(res) # 输出结果如下 区域 户型 CBD租房 1室1厅 10700.000000 2室1厅 14250.000000 2室2厅 16000.000000 3室1厅 21333.333333 4室2厅 18000.000000 ... 鼓楼大街租房 1室0厅 1900.000000 1室1厅 1800.000000 2室1厅 3800.000000 2室2厅 4000.000000 3室1厅 4544.444444
1.2 取出每组第一条或最后一条数据
gs = df.groupby(by=['区域', '户型'])
# 获取每组第一条数据
print(gs.first())
# 获取每组最后一条数据
print(gs.last())
# 输出结果如下
地址 面积 价格 朝向 更新时间 看房人数
区域 户型
CBD租房 1室1厅 和乔丽致公寓 61 12000 北 2017.07.27 2
2室1厅 金地国际花园 124 19000 南 2017.07.18 16
2室2厅 盛世嘉园 161 16000 南 2017.07.27 1
3室1厅 SOHO现代城 143 15000 西 2017.07.14 31
4室2厅 阳光100 173 18000 东南 东北 2017.07.14 3
... ... ... ... ... ... ...
鼓楼大街租房 1室0厅 北环里小区 37 1900 东 2017.07.21 7
1室1厅 北环里小区 41 1800 东 2017.07.23 9
2室1厅 邑上苑 88 4000 南 北 2017.07.23 0
2室2厅 金隅万科城 89 4000 东南 2017.07.25 19
3室1厅 金隅万科城 88 4800 南 北 2017.07.26 31
[793 rows x 6 columns]
地址 面积 价格 朝向 更新时间 看房人数
区域 户型
CBD租房 1室1厅 和乔丽致公寓 61 12000 北 2017.07.14 9
2室1厅 建国路100号 61 6000 东 2017.07.20 2
2室2厅 盛世嘉园 161 16000 南 2017.07.27 1
3室1厅 金地国际花园 197 27000 西南 北 2017.07.15 6
4室2厅 阳光100 173 18000 东南 东北 2017.07.14 3
... ... ... ... ... ... ...
鼓楼大街租房 1室0厅 北环里小区 37 1900 东 2017.07.21 7
1室1厅 北环里小区 41 1800 东 2017.07.23 9
2室1厅 金隅万科城 85 4000 南 2017.07.26 0
2室2厅 金隅万科城 89 4000 东南 2017.07.25 19
3室1厅 蔚府 108 5500 南 北 2017.07.23 1
[793 rows x 6 columns]
1.3 获取分组后每组的名称
print(gs.grouper.result_index)
# 输出结果如下
MultiIndex([( 'CBD租房', '1室1厅'),
( 'CBD租房', '2室1厅'),
( 'CBD租房', '2室2厅'),
( 'CBD租房', '3室1厅'),
( 'CBD租房', '4室2厅'),
( '七里庄租房', '1室0厅'),
( '七里庄租房', '1室1厅'),
( '七里庄租房', '2室1厅'),
( '七里庄租房', '3室1厅'),
( '七里庄租房', '3室2厅'),
...
( '黄村北租房', '3室2厅'),
( '黄村北租房', '4室2厅'),
('黄村火车站租房', '2室1厅'),
('黄村火车站租房', '3室1厅'),
('黄村火车站租房', '3室2厅'),
( '鼓楼大街租房', '1室0厅'),
( '鼓楼大街租房', '1室1厅'),
( '鼓楼大街租房', '2室1厅'),
( '鼓楼大街租房', '2室2厅'),
( '鼓楼大街租房', '3室1厅')],
names=['区域', '户型'], length=793)
1.4 gs.get_group()
按分组依据获取其中一组
print(gs.get_group(name=('CBD租房', '1室1厅')))
# 输出结果如下
区域 地址 户型 面积 价格 朝向 更新时间 看房人数
624 CBD租房 和乔丽致公寓 1室1厅 61 12000 北 2017.07.27 2
645 CBD租房 和乔丽致公寓 1室1厅 61 12000 北 2017.07.27 2
1359 CBD租房 和乔丽致公寓 1室1厅 61 11000 西 2017.07.15 3
1383 CBD租房 和乔丽致公寓 1室1厅 61 11000 西 2017.07.15 3
2073 CBD租房 光辉南里 1室1厅 55 6200 东 南 2017.07.21 9
2562 CBD租房 和乔丽致公寓 1室1厅 61 12000 北 2017.07.14 9
2 分组聚合
2.1 分组后直接聚合
分组后直接进行聚合计算并返回df
df.groupby(by=[列名1, 列名2, ...]).聚合函数()
-
按区域分组, 计算每组的各数值列的平均值
res = df.groupby(['区域']).mean() print(res) # 输出结果如下 面积 价格 看房人数 区域 CBD租房 113.375000 14700.000000 6.750000 七里庄租房 82.941176 5617.647059 13.764706 万寿路租房 63.875000 6575.000000 14.875000 万柳租房 137.916667 18629.166667 16.541667 三元桥租房 103.045455 12581.818182 12.590909 ... ... ... ... 鲁谷租房 80.684211 6381.578947 11.421053 黄村中租房 84.000000 3775.000000 3.250000 黄村北租房 104.684211 5631.578947 14.473684 黄村火车站租房 77.666667 3166.666667 7.666667 鼓楼大街租房 89.000000 3987.500000 6.937500 [208 rows x 3 columns]
2.2 分组后指定单列或多列聚合
根据1列或多列的值进行分组后, 每一组都对指定列的值使用聚合函数(比如mean求平均值)进行计算
对一列聚合可以使用一个[], 返回series对象; 也可以使用两个[], 返回dataframe对象
对多列聚合建议使用两个[[]], 返回dataframe对象
df.groupby(['列名1', '列名2'])['指定列1'].聚合函数()
df.groupby(['列名1', '列名2'])[['指定列1', '指定列2', ...]].聚合函数()
-
按区域分组, 计算每组价格的平均值
# 返回series对象 res = df.groupby(['区域'])['价格'].mean() print(res) # 返回dataframe对象 res = df.groupby(['区域'])[['价格']].mean() print(res) # 输出结果如下 区域 CBD租房 14700.000000 七里庄租房 5617.647059 万寿路租房 6575.000000 万柳租房 18629.166667 三元桥租房 12581.818182 ... 鲁谷租房 6381.578947 黄村中租房 3775.000000 黄村北租房 5631.578947 黄村火车站租房 3166.666667 鼓楼大街租房 3987.500000 Name: 价格, Length: 208, dtype: float64 价格 区域 CBD租房 14700.000000 七里庄租房 5617.647059 万寿路租房 6575.000000 万柳租房 18629.166667 三元桥租房 12581.818182 ... ... 鲁谷租房 6381.578947 黄村中租房 3775.000000 黄村北租房 5631.578947 黄村火车站租房 3166.666667 鼓楼大街租房 3987.500000 [208 rows x 1 columns]
-
按区域分组, 计算每组价格和看房人数的平均值
res = df.groupby(['区域'])[['价格', '看房人数']].mean() print(res) # 输出结果如下 价格 看房人数 区域 CBD租房 14700.000000 6.750000 七里庄租房 5617.647059 13.764706 万寿路租房 6575.000000 14.875000 万柳租房 18629.166667 16.541667 三元桥租房 12581.818182 12.590909 ... ... ... 鲁谷租房 6381.578947 11.421053 黄村中租房 3775.000000 3.250000 黄村北租房 5631.578947 14.473684 黄村火车站租房 3166.666667 7.666667 鼓楼大街租房 3987.500000 6.937500 [208 rows x 2 columns]
2.3 分组后使用多个聚合函数
同时使用多个内置聚合函数,全部放入一个Python列表, 然后把整个列表传入agg或aggregate函数中;返回以分组列作为索引,每一个聚合计算结果作为列的全新df
df.groupby(['列名1', '列名2'])[['指定列1', '指定列2']].agg(['max', 'min'])
max, min 为pandas内置的聚合函数名
-
按区域分组, 计算每组价格和看房人数的平均值和总数
res = df.groupby(['区域'])[['价格', '看房人数']].agg(['mean', 'sum']) print(res) # 输出结果如下 价格 看房人数 mean sum mean sum 区域 CBD租房 14700.000000 235200 6.750000 108 七里庄租房 5617.647059 95500 13.764706 234 万寿路租房 6575.000000 52600 14.875000 119 万柳租房 18629.166667 447100 16.541667 397 三元桥租房 12581.818182 276800 12.590909 277 ... ... ... ... ... 鲁谷租房 6381.578947 242500 11.421053 434 黄村中租房 3775.000000 15100 3.250000 13 黄村北租房 5631.578947 107000 14.473684 275 黄村火车站租房 3166.666667 9500 7.666667 23 鼓楼大街租房 3987.500000 63800 6.937500 111 [208 rows x 4 columns]
2.4 分组后对多列分别使用不同的聚合函数
agg
函数中可以传入字典,字典的key是df的列名,与key对应的value是pandas内置的聚合计算函数、其名称的字符串;返回以分组列作为索引,每一个聚合计算结果作为列的全新df
df.groupby(['列名1', '列名2']).agg({ '指定列1':'mean', '指定列2':'sum', '指定列3':'mean' })
-
按区域分组, 计算每组价格的平均值和看房人数的总数
res = df.groupby(['区域']).agg({'价格': 'mean', '看房人数': 'sum'}) print(res) # 输出结果如下 价格 看房人数 区域 CBD租房 14700.000000 108 七里庄租房 5617.647059 234 万寿路租房 6575.000000 119 万柳租房 18629.166667 397 三元桥租房 12581.818182 277 ... ... ... 鲁谷租房 6381.578947 434 黄村中租房 3775.000000 13 黄村北租房 5631.578947 275 黄村火车站租房 3166.666667 23 鼓楼大街租房 3987.500000 111 [208 rows x 2 columns]
2.5 分组后使用自定义聚合函数
分组之后指定列,对该列的值使用自定义的函数
def bar(s, args1, args2):
'''自定义函数
s,为传入的series对象
args1,args2为自定义传参
'''
s_mean = s.sum() / s.size
return s_mean + args1 + args2
# 调用自定义函数
df.groupby(['列名1', '列名2']).agg(bar, args1=xxx, args2=xxx)
df.groupby(['列名1', '列名2'])['指定列1', '指定列2'].agg(bar, args1=xxx, args2=xxx)
-
按区域分组, 计算每组价格和看房人数的平均值
# 定义自定义函数 def func(s): # 参数s是分组之后指定的每一列 s_mean = s.sum() / s.size return s_mean res = df.groupby('区域')[['价格', '看房人数']].agg(func) print(res) # 与下面的代码效果相同 # df.groupby('区域')[['价格', '看房人数']].mean() # 输出结果如下 价格 看房人数 区域 CBD租房 14700.000000 6.750000 七里庄租房 5617.647059 13.764706 万寿路租房 6575.000000 14.875000 万柳租房 18629.166667 16.541667 三元桥租房 12581.818182 12.590909 ... ... ... 鲁谷租房 6381.578947 11.421053 黄村中租房 3775.000000 3.250000 黄村北租房 5631.578947 14.473684 黄村火车站租房 3166.666667 7.666667 鼓楼大街租房 3987.500000 6.937500 [208 rows x 2 columns]
3 数据离散化(分箱)
-
pd.cut()
函数用来把一组数据分割成离散的区间。比如有一组年龄数据,可以使用pandas.cut
将价格数据分割成不同的价格段并打上标签。上述过程又叫做分箱。pd.cut(x=Seriers对象, bins=3, labels=['低', '中', '高'])
-
离散化分箱函数的常用参数有:
- x 指定离散化(分箱)依据的列,Seriers对象
- bins 分为几组,int类型,也可以传入分组区间的列表
- labels 每组的标签名称,按数值由小到大的顺序
- right 默认True:左开右闭;False:左闭右开
- include_lowest 默认False:不包含第一个分组的起始值;True:包含
-
按价格金额大小分为3组,将每条数据都打上高中低的标签
df2 = df.copy() # 复制数据集 # 分箱返回Seriers对象并复制给新的列 df2['价格高中低'] = pd.cut(x=df2['价格'], bins=3, labels=['低', '中', '高']) # df2['价格高中低'] = pd.cut(x=df2['价格'], bins=[0,3000,8000,210000], labels=['低', '中', '高']) df2
总结
请对下面的内容 有印象、能找到、能理解、能看懂
-
分组对象
gs = df.groupby(['列1', '列2'])
按照列1、列2的值对数据集进行分组,返回分组对象gs.first()
返回每组的第一条数据gs.last()
返回每组的最后一条数据gs.grouper.result_index
获取全部组名gs.get_group((组名))
按照
-
分组聚合
-
分组后直接聚合
df.groupby(['列名1', '列名2']).聚合函数()
-
分组后指定单列或多列聚合
df.groupby(['列名1', '列名2'])['指定列'].聚合函数()
-
分组后使用多个聚合函数
df.groupby(['列名1', '列名2'])[['指定列1', '指定列2']].agg(['max', 'min'])
-
分组后对多列分别使用不同的聚合函数
df.groupby(['列名1', '列名2']).agg({ '指定列1':'mean', '指定列2':'sum', '指定列3':'mean' })
-
分组后使用自定义聚合函数
def foo(s): # 参数s 是分组之后指定的每一列 s_mean = s.sum() / s.size return s_mean df.groupby(['列名1', '列名2'])[['指定列1', '指定列2']].agg(foo)
-
-
数据离散化(分箱)用来把一组数据分割成若干个离散的区间。比如有一组年龄数据,可以使用
pandas.cut
将年龄数据分割成不同的年龄段并打上标签。上述过程又叫做分箱。-
参数x 指定离散化(分箱)依据的列,Seriers对象
-
参数bins 分为几组,int类型,也可以传入分组区间的列表
-
参数labels 每组的标签名称,按数值由小到大的顺序
-
参数right 默认True:左开右闭;False:左闭右开
‘指定列3’:‘mean’
}) -
分组后使用自定义聚合函数
def foo(s): # 参数s 是分组之后指定的每一列 s_mean = s.sum() / s.size return s_mean df.groupby(['列名1', '列名2'])[['指定列1', '指定列2']].agg(foo)
-
-
数据离散化(分箱)用来把一组数据分割成若干个离散的区间。比如有一组年龄数据,可以使用
pandas.cut
将年龄数据分割成不同的年龄段并打上标签。上述过程又叫做分箱。- 参数x 指定离散化(分箱)依据的列,Seriers对象
- 参数bins 分为几组,int类型,也可以传入分组区间的列表
- 参数labels 每组的标签名称,按数值由小到大的顺序
- 参数right 默认True:左开右闭;False:左闭右开
- 参数include_lowest 默认False:不包含第一个分组的起始值;True:包含