In [1]: import numpy as np
In [2]: import pandas as pd
1. cat对象的属性
在 pandas
中提供了 category
类型,使用户能够处理分类类型的变量,将一个普通序列转换成分类变量可以使用 astype
方法。
In [3]: df = pd.read_csv('data/learn_pandas.csv',
...: usecols = ['Grade', 'Name', 'Gender', 'Height', 'Weight'])
...:
In [4]: s = df.Grade.astype('category')
In [5]: s.head()
Out[5]:
0 Freshman
1 Freshman
2 Senior
3 Sophomore
4 Sophomore
Name: Grade, dtype: category
Categories (4, object): ['Freshman', 'Junior', 'Senior', 'Sophomore']
在一个分类类型的 Series
中定义了 cat
对象,它和上一章中介绍的 str
对象类似,定义了一些属性和方法来进行分类类别的操作。
In [6]: s.cat
Out[6]: <pandas.core.arrays.categorical.CategoricalAccessor object at 0x0000026403481608>
对于一个具体的分类,有两个组成部分,其一为类别的本身,它以 Index
类型存储,其二为是否有序,它们都可以通过 cat
的属性被访问:
In [7]: s.cat.categories
Out[7]: Index(['Freshman', 'Junior', 'Senior', 'Sophomore'], dtype='object')
In [8]: s.cat.ordered
Out[8]: False
另外,每一个序列的类别会被赋予唯一的整数编号,它们的编号取决于 cat.categories
中的顺序,该属性可以通过 codes
访问:
In [9]: s.cat.codes.head()
Out[9]:
0 0
1 0
2 2
3 3
4 3
dtype: int8
2. 类别的增加、删除和修改
通过 cat
对象的 categories
属性能够完成对类别的查询,那么应该如何进行“增改查删”的其他三个操作呢?
类别不得直接修改
在 第三章 中曾提到,索引
Index
类型是无法用index_obj[0] = item
来修改的,而categories
被存储在Index
中,因此pandas
在cat
属性上定义了若干方法来达到相同的目的。
首先,对于类别的增加可以使用 add_categories
:
In [10]: s = s.cat.add_categories('Graduate') # 增加一个毕业生类别
In [11]: s.cat.categories
Out[11]: Index(['Freshman', 'Junior', 'Senior', 'Sophomore', 'Graduate'], dtype='object')
若要删除某一个类别可以使用 remove_categories
,同时所有原来序列中的该类会被设置为缺失。例如,删除大一的类别:
In [12]: s = s.cat.remove_categories('Freshman')
In [13]: s.cat.categories
Out[13]: Index(['Junior', 'Senior', 'Sophomore', 'Graduate'], dtype='object')
In [14]: s.head()
Out[14]:
0 NaN
1 NaN
2 Senior
3 Sophomore
4 Sophomore
Name: Grade, dtype: category
Categories (4, object): ['Junior', 'Senior', 'Sophomore', 'Graduate']
此外可以使用 set_categories
直接设置序列的新类别,原来的类别中如果存在元素不属于新类别,那么会被设置为缺失。
In [15]: s = s.cat.set_categories(['Sophomore','PhD']) # 新类别为大二学生和博士
In [16]: s.cat.categories
Out[16]: Index(['Sophomore', 'PhD'], dtype='object')
In [17]: s.head()
Out[17]:
0 NaN
1 NaN
2 NaN
3 Sophomore
4 Sophomore
Name: Grade, dtype: category
Categories (2, object): ['Sophomore', 'PhD']
如果想要删除未出现在序列中的类别,可以使用 remove_unused_categories
来实现:
In [18]: s = s.cat.remove_unused_categories() # 移除了未出现的博士生类别
In [19]: s.cat.categories
Out[19]: Index(['Sophomore'], dtype='object')
最后,“增改查删”中还剩下修改的操作,这可以通过 rename_categories
方法完成,同时需要注意的是,这个方法会对原序列的对应值也进行相应修改。例如,现在把 Sophomore
改成中文的 本科二年级学生
:
In [20]: s = s.cat.rename_categories({'Sophomore':'本科二年级学生'})
In [21]: s.head()
Out[21]:
0 NaN
1 NaN
2 NaN
3 本科二年级学生
4 本科二年级学生
Name: Grade, dtype: category
Categories (1, object): ['本科二年级学生']