內容目錄
- 1. 創建對象
- 2. 常用操作
- 3. 內存使用量的陷阱
一、創建對象
- 1.基本概念:分類數據直白來說就是取值為有限的,或者說是固定數量的可能值。例如:性別、血型。
- 2.創建分類數據:這里以血型為例,假定每個用戶有以下的血型,我們如何創建一個關於血型的分類對象呢?
方法一:明確指定 dtype="category"
index = pd.Index(data=["Tom", "Bob", "Mary", "James", "Andy", "Alice"], name="name") user_info = pd.Series(data=["A", "AB", np.nan, "AB", "O", "B"], index=index, name="blood_type", dtype="category") user_info Out[6]: name Tom A Bob AB Mary NaN James AB Andy O Alice B Name: blood_type, dtype: category Categories (4, object): [A, AB, B, O]
方法二:使用 pd.Categorical 來構建分類數據。
pd.Categorical(["A", "AB", np.nan, "AB", "O", "B"]) Out[7]: [A, AB, NaN, AB, O, B] Categories (4, object): [A, AB, B, O]
- 3.自己制定類別數據所有可能的取值。
假定我們認為血型只有 A、B 以及 AB 這三類,那么我們可以這樣操作。
#定制分類數據所有可能的取值 pd.Categorical(["A", "AB", np.nan, "AB", "O", "B"], categories=["A", "B", "AB"]) Out[8]: [A, AB, NaN, AB, NaN, B] Categories (3, object): [A, B, AB]
- 4.Series轉為分類數據,astype
#將遺傳序列轉化為分類數據
user_info = pd.Series(data=["A", "AB", np.nan, "AB", "O", "B"], index=index, name="blood_type")
user_info = user_info.astype("category")
user_info
Out[9]:
name
Tom A
Bob AB
Mary NaN
James AB
Andy O
Alice B
Name: blood_type, dtype: category
Categories (4, object): [A, AB, B, O]
- 5.此外,一些其他的方法返回的結果也是分類數據。如 cut 、 qcut。具體可以見 Pandas基本功能詳解中的離散化部分。
二、常用操作
可以對分類數據使用 .describe() 方法,它得到的結果與 string類型的數據相同。
count 表示非空的數據有5條,unique 表示去重后的非空數據有4條,top 表示出現次數最多的值為 AB,
freq 表示出現次數最多的值的次數為2次。
我們可以使用 .cat.categories 來獲取分類數據所有可能的取值。
重命名分類數據:cat.rename_categories
添加分類數據:.cat.add_categories
刪除分類數據:.cat.remove_categories
查看數據分布:.value_counts()
通過.str訪問
合並數據,用concat,類型變為object
保留分類數據類型,union_categoricals
user_info.describe()
Out[86]:
count 5
unique 4
top AB
freq 2
Name: blood_type, dtype: object
user_info.cat.rename_categories(["A+", "AB+", "B+", "O+"])
Out[87]:
name
Tom A+
Bob AB+
Mary NaN
James AB+
Andy O+
Alice B+
Name: blood_type, dtype: category
Categories (4, object): [A+, AB+, B+, O+]
user_info.str.contains('A')
Out[88]:
name
Tom True
Bob True
Mary NaN
James True
Andy False
Alice False
Name: blood_type, dtype: object
#合並數據
blood_type1 = pd.Categorical(["A", "AB"])
blood_type2 = pd.Categorical(["B", "O"])
pd.concat([pd.Series(blood_type1), pd.Series(blood_type2)])
Out[89]:
0 A
1 AB
0 B
1 O
dtype: object
#保留分類數據
from pandas.api.types import union_categoricals
union_categoricals([blood_type1, blood_type2])
Out[90]:
[A, AB, B, O]
Categories (4, object): [A, AB, B, O]
cat所有屬性
[name for name in user_info.cat.__dir__() if not name.startswith('_')]
Out[92]:
['add_categories',
'as_ordered',
'as_unordered',
'categories',
'codes',
'ordered',
'remove_categories',
'remove_unused_categories',
'rename_categories',
'reorder_categories',
'set_categories']
三、內存使用量的陷阱
Categorical 的內存使用量是與分類數乘以數據長度成正比,object 類型的數據是一個常數乘以數據的長度。
blood_type = pd.Series(["AB","O"]*1000)
blood_type.nbytes
Out[79]: 16000
blood_type.astype("category").nbytes
Out[80]: 2016
blood_type = pd.Series(['AB%4d' % i for i in range(2000)])
blood_type.nbytes
Out[81]: 16000
blood_type.astype("category").nbytes
Out[82]: 20000
