用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],
})
資料形式展示:
name | age | score | |
---|---|---|---|
A | 23 | 13 | |
1 | B | 26 | 23 |
2 | C | 37 | 22 |
3 | D | 46 | 76 |
4 | E | 85 | 56 |
5 | F | 12 | 89 |
6 | G | 53 | 99 |
7 | H | 80 | 100 |
8 | I | 66 | 10 |
9 | J | 32 | 54 |
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,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:[“不及格”,“良好”,“優秀”]
傳回的是對應的标簽,而不是對應的區間
代碼運作結果:
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=["不及格","良好","優秀"])
代碼運作結果:
name | age | score | age_range | score_label | |
---|---|---|---|---|---|
A | 23 | 13 | (20, 30] | 不及格 | |
1 | B | 26 | 23 | (20, 30] | 不及格 |
2 | C | 37 | 22 | (30, 50] | 不及格 |
3 | D | 46 | 76 | (30, 50] | 良好 |
4 | E | 85 | 56 | (80, 90] | 不及格 |
5 | F | 12 | 89 | (10, 20] | 優秀 |
6 | G | 53 | 99 | (50, 70] | 優秀 |
7 | H | 80 | 100 | (70, 80] | 優秀 |
8 | I | 66 | 10 | (50, 70] | 不及格 |
9 | J | 32 | 54 | (30, 50] | 不及格 |