8-Pandas擴展之分類數據處理(分類數據的概念、創建、常用操作)


 一、分類數據的概念

1、什么是分類數據

  分類數據(Category Data)是指Pandas數據類型為分類類型的數據

  分類數據是由固定的且數量有限的變量組成,通常是字符串。例如:

    • 性別:男、女
    • 血型:A型、B型、C型
    • 國家:中國、美國、德國

  分類數據可以設置邏輯順序,如:高 > 中 > 低

>>> df = pd.read_excel('C:/Users/xhl/Desktop/input/class.xlsx')
>>> df
  class     sex  score_math  score_music
0     A    male          95           79
1     A  female          96           90
2     B  female          85           85
3     C    male          93           92
4     B  female          84           90
5     B    male          88           70
6     C    male          59           89
7     A    male          88           86
8     B    male          89           74
>>> df.dtypes
class          object
sex            object
score_math      int64
score_music     int64
dtype: object

  使用astype()將性別轉換成分類類型

>>> df['sex'].astype('category')
0      male
1    female
2    female
3      male
4    female
5      male
6      male
7      male
8      male
Name: sex, dtype: category
Categories (2, object): [female, male]

2、分類數據的values

  分類數據的values值是一個pandas.Categorical對象,而不再是Numpy對象

#未分類時
>>> type(df['sex'].values)
<class 'numpy.ndarray'>
#分類后
>>> type(df['sex'].astype('category').values)
<class 'pandas.core.arrays.categorical.Categorical'>

3、分類數據的屬性

     包括類別(categories)編碼(codes)兩個屬性;

   分類數據將一個類別映射到一個整數上,其內部數據結構一個類別數組和一個整數數組構成

>>> sex_cate = df['sex'].astype('category')
>>> sex_cate.values
[male, female, female, male, female, male, male, male, male]
Categories (2, object): [female, male]
#查看類別
>>> sex_cate.values.categories
Index(['female', 'male'], dtype='object')
查看編碼
>>> sex_cate.values.codes
array([1, 0, 0, 1, 0, 1, 1, 1, 1], dtype=int8)

4、使用分類數據的好處

   分類數據通過將類別進行數字編碼,可以大大節省內存的占用,提高運行速度,可使用memory_usage()檢驗

5、為何使用分類數據?

  分類數據可以指定邏輯順序,並能夠進行邏輯順序上的排序篩選最大/最小值的操作

   使用Series.cat.as_ordered()可設置邏輯順序,但並沒有什么實際含義,並不怎么常用

>>> df['class'].astype('category').cat.as_ordered()
0    A
1    A
2    B
3    C
4    B
5    B
6    C
7    A
8    B
Name: class, dtype: category
Categories (3, object): [A < B < C]

  使用Series.cat.set_categories()自定義邏輯順序,有實際含義

>>> df['class'].astype('category').cat.set_categories(["C","B","A"])
0    A
1    A
2    B
3    C
4    B
5    B
6    C
7    A
8    B
Name: class, dtype: category
Categories (3, object): [C, B, A]

  分類數據的排序仍然使用sort_values()

>>> df['class'].astype('category').cat.set_categories(['C','B','A']).sort_values()
3    C
6    C
2    B
4    B
5    B
8    B
0    A
1    A
7    A
Name: class, dtype: category
Categories (3, object): [C, B, A]

  篩選最大值與最小值

>>> df['class'].astype('category').cat.as_ordered().min()
'A'
>>> df['class'].astype('category').cat.as_ordered().max()
'C'

二、分類數據的創建

 1、通過參數dtype創建分類數據

  創建Series或DataFrame時,可指定參數dtype = ‘category’創建Series或DataFrame

#創建Series
>>> s = pd.Series(['female','male','male'],dtype='category')
>>> s
0    female
1      male
2      male
dtype: category
Categories (2, object): [female, male]

#創建DataFrame
>>> df = pd.DataFrame({'sex':['female','male','male'],'grade':list('BAB')},dtype='category')
>>> df
      sex grade
0  female     B
1    male     A
2    male     B
>>> df.dtypes
sex      category
grade    category
dtype: object

2、通過pd.Categorical對象創建分類數據

  創建一個pd.Categorical對象,並將其傳入Series或者DataFrame,即可創建分類數據

>>> c = pd.Categorical(['C','A','B'])
>>> c
[C, A, B]
Categories (3, object): [A, B, C]

>>> c_df = pd.Categorical({'sex':['female','male','male'],'grade':list('BAB')})
>>> c_df
[sex, grade]
Categories (2, object): [grade, sex]

>>> df = pd.DataFrame({'sex':['female','male','male']})
>>> df['grade'] = c
>>> df
      sex grade
0  female     C
1    male     A
2    male     B
>>> df.dtypes
sex        object
grade    category
dtype: object

  在創建pd.Categorical對象時,可以通過參數categoeies指定類別,沒被指定的數據則會顯示為缺失值

>>> c = pd.Categorical(['C','A','B','A'],categories=['A','B'])
>>> s = pd.Series(c)
>>> s
0    NaN
1      A
2      B
3      A
dtype: category
Categories (2, object): [A, B]

3、通過pd.Categorical.from_codes創建分類數據

  當已知類別編碼時,可通過pd.Categorical.from_codes創建分類數據;

>>> categories = ['female','male']
>>> codes = [1,1,1,0,0,1,0]
>>> c = pd.Categorical.from_codes(codes,categories)
>>> c
[male, male, male, female, female, male, female]
Categories (2, object): [female, male]

>>> categories = ['female','male','unkonw']
>>> codes = [1,2,0,0,1,0]
>>> c = pd.Categorical.from_codes(codes,categories)
>>> c
[male, unkonw, female, female, male, female]
Categories (3, object): [female, male, unkonw]

  注意:此時的categories = ['female','male','unkonw']的對應的codes值分別為0,1,2....。

4、通過cut()/qcut()創建分類數據---分類數值型數據

  使用cut()/qcut()進行離散化會自動轉為分類類型。

>>> math = pd.cut(df['score_math'],[0,60,80,100],right=False)
>>> math[:3]
0    [80, 100)
1    [80, 100)
2    [80, 100)
Name: score_math, dtype: category
Categories (3, interval[int64]): [[0, 60) < [60, 80) < [80, 100)]

#使用參數lables修改類別名稱
>>> math = pd.cut(df['score_math'],[0,60,80,100],right=False,labels=['C','B','A'])
>>> math[:3]
0    A
1    A
2    A
Name: score_math, dtype: category
Categories (3, object): [C < B < A]

  結合groupby()查看分類數據:修改后的成績等級無法看到分數區間的范圍,可結合groupby查看各最大值、最小值等:

>>> df['score_math'].groupby(math).agg(['count','max','min'
            count   max   min
score_math
C               1  59.0  59.0
B               0   NaN   NaN
A               8  96.0  84.0  

三、分類數據的常用操作方法

 1、分類數據的特殊屬性Series.cat

  包含分類數據的Series有很多操作方法,可通過特殊屬性Series.cat訪問;

  通過Series.cat查看其類別categories和編碼codes.

>>> s = pd.Series(pd.Categorical(['C','A','B','C']))
>>> s
0    C
1    A
2    B
3    C
dtype: category
Categories (3, object): [A, B, C]

>>> s.cat.categories
Index(['A', 'B', 'C'], dtype='object')

>>> s.cat.codes
0    2
1    0
2    1
3    2
dtype: int8

2、分類數據的常用操作方法

方法 說明
rename_categories 更改類別名稱
add_categories 添加新類別
remove_categories 刪除類別
remove_unused_categories 刪除數據中沒有出現的類別
set_categories 替換、增加和刪除類別
as_ordered 分類數據設置有邏輯順序
as_unordered 分類數據設置無邏輯順序
reorder_categories 重排分類數數據的順序

 

 

 

 

 

 

 

 

 

 

 

 

(1)更改類別名稱-----可通過傳入字典的方式進行更改

>>> s1 = s.cat.rename_categories({'A':'grade A','B':'grade B','C':'grade C'})
>>> s1
0    grade C
1    grade A
2    grade B
3    grade C
dtype: category
Categories (3, object): [grade A, grade B, grade C]

(2)添加新類別

>>> s2 = s.cat.add_categories('D')
>>> s2
0    C
1    A
2    B
3    C
dtype: category
Categories (4, object): [A, B, C, D]

(3)刪除類別

  注意:被刪除的類別在數據集中顯示值為空值

>>> s3 = s2.cat.remove_categories('D')
>>> s3
0    C
1    A
2    B
3    C
dtype: category
Categories (3, object): [A, B, C]

>>> s4 = s2.cat.remove_categories('A')
>>> s4
0      C
1    NaN
2      B
3      C
dtype: category
Categories (3, object): [B, C, D]

(4)刪除數據中沒有出現的類別remove_categories只能刪除某一特定的類別,並不能確定哪些類別並未使用過

>>> s2
0    C
1    A
2    B
3    C
dtype: category
Categories (4, object): [A, B, C, D]
>>> s5 = s2.cat.remove_unused_categories()
>>> s5
0    C
1    A
2    B
3    C
dtype: category
Categories (3, object): [A, B, C]

(5)同時添加或刪除類別,使用set_categories,只需將需要的類別直接set即可

>>> s6 = s2.cat.set_categories(['B','C','E'])
>>> s6
0      C
1    NaN
2      B
3      C
dtype: category
Categories (3, object): [B, C, E]

(6)設置邏輯順序

  分類數據的邏輯順序可以通過as_ordered進行設置,也可以通過as_unordered設置為無邏輯順序

>>> s_ordered = s2.cat.as_ordered()
>>> s_ordered
0    C
1    A
2    B
3    C
dtype: category
Categories (4, object): [A < B < C < D]

>>> s_unordered = s_ordered.cat.as_unordered()
>>> s_unordered
0    C
1    A
2    B
3    C
dtype: category
Categories (4, object): [A, B, C, D]

  在設置分類數據時,也可通過設置參數ordered = True設置邏輯順序

>>> s_ordered_new = s2.cat.set_categories(['C','B','A'],ordered=True)
>>> s_ordered_new
0    C
1    A
2    B
3    C
dtype: category
Categories (3, object): [C < B < A]

(7)重排邏輯順序

  方法一:前面已介紹,可通過set_categories自定義邏輯順序

  方法二:通過reorde_categories方法重排邏輯順序

>>> s_or = s.cat.reorder_categories(['B','C','A'],ordered=True)
>>> s_or
0    C
1    A
2    B
3    C
dtype: category
Categories (3, object): [B < C < A]

 注意:使用reorder_categories方法不能添加或刪除類別,否則會報錯

>>>s.cat.reorder_categories(['B','C','A','D'],ordered=True)
ValueError: items in new_categories are not the same as in old categories

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM