Pandas中节约空间的小tip——Categorical类型
本文作者:孙晓玲
categorical是Pandas中的分类类型数据,当数据只有少数几种可能取值但有大量重复字符串字段,利用categorical类型可有效节省内存,提高数据分析的效率。常见的分类如性别、职业等取值有限的类别数据。
一、categorical的创建
Pandas中创建categorical
型数据的方法很多,主要有以下三种途径。
1.由Series数据结构转换。在生成Series时传入参数dtype="category"
,直接创建categorical
型Series。
import numpy as np
import pandas as pd
index = pd.Index(data=['Tom','Mary','Andy','Bob','Alice','James','Lily','Mike'], name="name")
series_cat=pd.Series(['teacher','student','clerk','student']*2, index=index,name='career',dtype='category')
series_cat
image
这样,就生成了一个名为career
具有三种职业类型的categorical
型Series。
2.由DataFrame数据转换。先生成DataFrame数组,再用df.astype修改指定列的数据类型为category
。
career = ['teacher','student','clerk','student']*2
sex=['man','female','female','man','female','man','female','man']
lens = len(career)
df = pd.DataFrame({'career': career,
'sex': sex,
'id': np.arange(lens),
'temperature': np.random.uniform(36, 38, size=lens)},
index=index,
columns=['id','career', 'sex', 'temperature'])
df
image
查看生成DataFrame数组发现,数组中career
和sex
为分类数据,再对career
和sex
列进行转换。
df_cat=df
df_cat['career']=df_cat['career'].astype('category')
df_cat['sex']=df_cat['sex'].astype('category')
print(df_cat['career'])
print(df_cat['sex'])
image
career
列和sex
列数据类型为分类数据。
3.由pd.Categorical()直接生成categorical型数据再转换为Series,或替换DataFrame中的指定内容。使用这种方法生成数据时,可用参数指定分类的类型及顺序。
categories = ['student', 'teacher', 'clerk']
codes = [1,0,2,0]*2
cat = pd.Categorical.from_codes(codes=codes, categories=categories)
cat
image
其中,codes和categories分别为categorical型数据的编码属性和分类属性。
ordered_cat = pd.Categorical.from_codes(codes, categories, ordered=True)
ordered_cat
image
想要获得指定排序的分类,向ordered参数传递布尔值True
,默认为False
。这里的职业分类并无强度关系,不需要传递。
series_cat=pd.Series(index=index,data=cat)
series_cat
image
二、Categorical的优良特性
1.用分类节省内存
在文章的开头就提到当数据只有少数几种可能取值但有大量重复字符串字段时,字符串占据的内存就比较大,利用Categorical类型对其转换后可有效节省内存。
N = 1000000
draws = pd.Series(np.random.randn(N))
series = pd.Series(['type1', 'type2', 'type3', 'type4'] * (N // 4))
categories = series.astype('category')
series.memory_usage()
categories.memory_usage()
image
明显看到分类数据占的内存比Series数据占据内存更小。当然,这个过程也付出了一定的代价,代价就是数据转换的时间。
%time _ = series.astype('category')
image
2.自定义排序
生成一个数据集,将其按评估结果排序:
df = pd.DataFrame({
'assessment':np.random.choice(['Bad','Very Bad','Good','Very Good'],10),
'score':np.random.uniform(0,10,10)
})
df.sort_values('assessment')
image
输出结果直接按首字母排序,并未按评估结果好坏排序。欲得到预期的排序结果,将制定的排序结果传递给数据集。
from pandas.api.types import CategoricalDtype
my_cat = CategoricalDtype(categories=['Very Good','Good','Bad','Very Bad'],
ordered=True)
df['assessment'] = df['assessment'].astype(my_cat)
df.sort_values('assessment')
image
今天就介绍到这里,Categorical的更多好用之处还在等待你的发掘!
网友评论