分类(Category)数据:直白来说,就是取值为有限的,或者说是固定数量的可能值。例如:性别、血型
指定数据类型构建分类数据
dtype="category"
以血型为例,创建一个关于血型的分类对象
import pandas as pd 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="bloo d_type", dtype="category") user_info """ name Tom A Bob AB Mary NaN James AB Andy O Alice B Name: bloo d_type, dtype: category Categories (4, object): [A, AB, B, O] """
使用 pd.Categorical 来构建分类数据
import pandas as pd 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") # categories:自定义类别数据 pd.Categorical(user_info, categories=["A", "B", "AB"]) """ [A, AB, NaN, AB, NaN, B] Categories (3, object): [A, B, AB] """
转为分类数据
我们经常遇到的情况是已经创建了一个 Series,如何将它转为分类数据呢?来看看 astype 用法吧
user_info = pd.Series(data=["A", "AB", np.nan, "AB", "O", "B"], index=index, name="bloo d_type") user_info = user_info.astype("category") user_info """ name Tom A Bob AB Mary NaN James AB Andy O Alice B Name: bloo d_type, dtype: category Categories (4, object): [A, AB, B, O] """
常用操作
.describe()
可以对分类数据使用 .describe() 方法,得到的结果与 string 类型的数据相同
user_info.describe() """ count 5 unique 4 top AB freq 2 Name: bloo d_type, dtype: object """ """ count:非空的数据有5条 unique:去重后的非空数据有4条 top:出现次数最多的值为 AB freq:出现次数最多的值的次数为2次。 """
.cat.categories
使用 .cat.categories 来获取分类数据所有可能的取值:
user_info.cat.categories """ Index(['A', 'AB', 'B', 'O'], dtype='object') """
.cat.rename_categories
使用 .cat.rename_categories 方法来重命名分类名称
user_info.cat.rename_categories(["A+", "AB+", "B+", "O+"])
添加、删除分类的操作,这些都可以通过 .cat.add_categories 、.cat.remove_categories 来实现。
.value_counts()
使用 value_counts 方法来查看数据分布的
user_info.value_counts()
.str 属性
使用 .str 属性来访问分类数据
# 查看是否包含字母 "A user_info.str.contains("A")
pd.concat
使用 pd.concat 分类数据合并
blood_type1 = pd.Categorical(["A", "AB"])
blood_type2 = pd.Categorical(["B", "O"]) pd.concat([pd.Series(blood_type1), pd.Series(blood_type2)])
union_categoricals
分类数据经过 pd.concat 合并后类型转为了 object 类型,如果想要保持分类类型的话,可以借助 union_categoricals 来完成。
from pandas.api.types import union_categoricals union_categoricals([blood_type1, blood_type2])
内存使用量
Categorical 的内存使用量是 与分类数乘以数据长度成正比
object 类型的数据 是一个 常数*数据的长度
在类别的数量很少的情况下,分类数据非常节省内存
blood_type = pd.Series(["AB","O"]*1000) blood_type.nbytes # 32000 blood_type.astype("category").nbytes # 4016
当类别的数量接近数据的长度,那么 Categorical 将使用与等效的 object 表示几乎相同或更多的内存
blood_type = pd.Series(['AB%04d' % i for i in range(2000)]) blood_type.nbytes # 16000 blood_type.astype("category").nbytes # 20000