Python数据分析实战【十三】:用pandas将数据划分区间【文末源码地址】


在数据分析的过程中,经常会遇到:年龄,收入,价格以及类似的数据,在数据分析前,需要将这些数据划分到一系列区间中,再将区间进行不同的编码,对编码后的数据进行分析。

在pandas中可以使用pandas.cut()方法实现对数据的区间划分,以及对区间进行标记。

案例数据

  • 以name,age,score为例,使用pandas.cut()方法对age、score进行区间划分。
import pandas as pd
import numpy as np

df = pd.DataFrame(data={
    "name":["A","B","C","D","E","F","G","H","I","J"],
    "age":[23,26,37,46,85,12,53,80,66,32],
    "score":[13,23,22,76,56,89,99,100,10,54],
})

数据形式展示:

nameagescore
0A2313
1B2623
2C3722
3D4676
4E8556
5F1289
6G5399
7H80100
8I6610
9J3254

pandas.cut()介绍

用来将数据划分为不同的区间

  • x:array型数据(DataFrame的每一列数据都是array型数据)
  • bins:传入int型数据,表示划分的区间个数,传入list型数据,表示自定义的区间
  • labels:传入与bins对应区间的标签list型数据(默认为None)
  • retbins:True表示返回划分的区间,False表示不返回划分的区间(默认为False)
  • right:True表示左开右闭,False表示左闭右开(默认为True)

返回数据:

  • x对应所在的区间,array类型
  • retbins为True时,还会返回划分区间

一、自动划分区间

例如:bins=3,right=True,pandas会将数据划分为3个区间,划分方法,

(max-(max-min)/bins,max]==>(60.667,85]

(max-(max-min)/bins*2,max-(max-min)/bins]==>(36.333.60.667]

(max-(max-min)/bins*3,max-(max-min)/bins*2]==>(11.927, 36.333]

a,b = pd.cut(x=df["age"],bins=3,right=True,retbins=True)
# a,bins传入的是int类型,自动生成的区间
0    (11.927, 36.333]
1    (11.927, 36.333]
2    (36.333, 60.667]
3    (36.333, 60.667]
4      (60.667, 85.0]
5    (11.927, 36.333]
6    (36.333, 60.667]
7      (60.667, 85.0]
8      (60.667, 85.0]
9    (11.927, 36.333]
Name: age, dtype: category
Categories (3, interval[float64]): [(11.927, 36.333] < (36.333, 60.667] < (60.667, 85.0]]
                                                                           
# b,自动划分的区间
array([11.927, 36.333, 60.667, 85.0])

二、自定义划分区间

eg:自定义一个年龄分段列表,age_bins = [10,20,30,50,70,80,90]

对应的区间为:[(10, 20] < (20, 30] < (30, 50] < (50, 70] < (70, 80] < (80, 90]]

这样pandas会按照age_bins指定的区间进行划分

age_bins = [10,20,30,50,70,80,90]
a,b = pd.cut(x=df["age"],bins=age_bins,right=True,retbins=True)

a和b的值:

# a返回的数据区间array对象
0    (20, 30]
1    (20, 30]
2    (30, 50]
3    (30, 50]
4    (80, 90]
5    (10, 20]
6    (50, 70]
7    (70, 80]
8    (50, 70]
9    (30, 50]
Name: age, dtype: category
Categories (6, interval[int64]): [(10, 20] < (20, 30] < (30, 50] < (50, 70] < (70, 80] < (80, 90]]

# b数据区间retbins=True
array([10, 20, 30, 50, 70, 80, 90])

三、区间左边是否包含

使用场景:当age为80的时候,应该归为(70,80]还是[80,90),这是个问题

eg:bins = [10,20,30,50,70,80,90],right=True

对应的区间为:[(10, 20] < (20, 30] < (30, 50] < (50, 70] < (70, 80] < (80, 90]]

pd.cut(x=df.age,bins=age_bins,retbins=True,right=True)

(0    (20, 30]
 1    (20, 30]
 2    (30, 50]
 3    (30, 50]
 4    (80, 90]
 5    (10, 20]
 6    (50, 70]
 7    (70, 80]
 8    (50, 70]
 9    (30, 50]
 Name: age, dtype: category
 Categories (6, interval[int64]): [(10, 20] < (20, 30] < (30, 50] < (50, 70] < (70, 80] < (80, 90]],
 array([10, 20, 30, 50, 70, 80, 90]))      

bins = [10,20,30,50,70,80,90],right=False

对应的区间为:[[10, 20) < [20, 30) < [30, 50) < [50, 70) < [70, 80) < [80, 90)]

pd.cut(x=df.age,bins=age_bins,retbins=True,right=False)

(0    [20, 30)
 1    [20, 30)
 2    [30, 50)
 3    [30, 50)
 4    [80, 90)
 5    [10, 20)
 6    [50, 70)
 7    [80, 90)
 8    [50, 70)
 9    [30, 50)
 Name: age, dtype: category
 Categories (6, interval[int64]): [[10, 20) < [20, 30) < [30, 50) < [50, 70) < [70, 80) < [80, 90)],
 array([10, 20, 30, 50, 70, 80, 90]))

四、区间加上标签

使用labels参数可以对区间加上标签,例如score列,小于60为不及格,60-80良好,80以上优秀

eg:bins:[0,60,80,100],labels:[“不及格”,“良好”,“优秀”]

返回的是对应的标签,而不是对应的区间

pd.cut(x=df.score,bins=[0,60,80,100],labels=["不及格","良好","优秀"])

代码运行结果:

0    不及格
1    不及格
2    不及格
3     良好
4    不及格
5     优秀
6     优秀
7     优秀
8    不及格
9    不及格
Name: score, dtype: category
Categories (3, object): ['不及格' < '良好' < '优秀']

给数据加上区间和标签

df["age_range"] = pd.cut(x=df["age"],bins=[10, 20, 30, 50, 70, 80, 90])
df["score_label"] = pd.cut(x=df["score"],bins=[0,60,80,100],labels=["不及格","良好","优秀"])

代码运行结果:

nameagescoreage_rangescore_label
0A2313(20, 30]不及格
1B2623(20, 30]不及格
2C3722(30, 50]不及格
3D4676(30, 50]良好
4E8556(80, 90]不及格
5F1289(10, 20]优秀
6G5399(50, 70]优秀
7H80100(70, 80]优秀
8I6610(50, 70]不及格
9J3254(30, 50]不及格
# 源码地址

链接:https://pan.baidu.com/s/1I24HGZz9_TXaaxXpeJKfqg?pwd=y80k
提取码:y80k

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

帅帅的Python

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值