内容目录
- 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