Pandas数据分析-Task10
记录DataWhale的Pandas数据分析的学习过程,使用的教材为 joyful-pandas。
Task10是pandas的类别数据处理,内容基本可以分为三个部分,第一部分介绍category类型的Series的cat对象的属性及类别的增删改等操作;第二部分介绍了有序的category类型,包括顺序的建立及建立后可以进行的一些操作;第三部分介绍了区间,经常需要将数值型的特征根据区间变为类别型的,pandas的一些区间函数可以派上用场。本篇文章中所有的代码示例中用到的原始文件都可以在 此链接中下载。
思维导图
练习1-统计未出现的类别
思路:my_crosstab(x,y,dropna)函数应该有三个参数,前两个参数x,y分别代表两个Series。先将输入的连个Series通过astype(‘category’)变为类别型数据,当dropna为True的时候,利用cat.remove_unused_categories()函数去除Series中没有出现的类别,然后利用cat.categories得到具体的类别;当dropna为False时,直接利用cat.categories得到具体的类别。将两个Series中的类别生成一个新的全零的DateFrame,接下来遍历两个Series,向DateFrame中填数字即可。
def my_crosstab(x,y,dropna=True):
if(dropna):
x_cat=x.astype('category').cat.remove_unused_categories().cat.categories.values
y_cat = y.astype('category').cat.remove_unused_categories().cat.categories.values
else:
x_cat = x.astype('category').cat.categories.values
y_cat = y.astype('category').cat.categories.values
df=pd.DataFrame(0,index=x_cat,columns=y_cat).rename_axis(index=x.name,columns=y.name)
for i in range(x.shape[0]):
df.loc[x[i],y[i]]+=1
return df
#测试
df = pd.DataFrame({'A':['a','b','c','a'],'B':['cat','cat','dog','cat']})
df.B = df.B.astype('category').cat.add_categories('sheep')
print(my_crosstab(df.A, df.B, dropna=False))
>>>
>B cat dog sheep
A
a 2 0 0
b 1 0 0
c 0 1 0
练习2-钻石数据集
1 .利用timeit模块直接对比时间即可
import timeit
df = pd.read_csv('data/diamonds.csv')
temp=df.cut.astype('category')
timeit.timeit(stmt='df.cut.unique()', setup='from __main__ import df', number=100)
>object的时间:0.1873
timeit.timeit(stmt='temp.unique()', setup='from __main__ import temp', number=100)
>category的时间:0.0524
可以看出,category类型的数据在执行unique()方法时更省时间。
2 .对类别进行排序,使用cat.reorder_categories()函数可以为类别型遍历建立顺序,再使用sort_values()即可进行排序。
df.cut=df.cut.astype('category').cat.reorder_categories(['Fair', 'Good', 'Very Good', 'Premium', 'Ideal'],ordered=True)
df.clarity=df.clarity.astype('category').cat.reorder_categories([ 'I1', 'SI2', 'SI1', 'VS2', 'VS1', 'VVS2', 'VVS1', 'IF'],ordered=True)
df=df.sort_values(by=['cut','clarity'],ascending=[False,True])
>>>
> carat cut clarity price
315 0.96 Ideal I1 2801
535 0.96 Ideal I1 2826
551 0.97 Ideal I1 2830
653 1.01 Ideal I1 2844
718 0.97 Ideal I1 2856
3 .两种方法实现由类别类型到序号的转化,第一种方法可以使用cat.codes属性;第二中是利用replace()函数完成替换。
#使用cat.codes属性
df['cut']=df.cut.astype('category').cat.reorder_categories(['Fair', 'Good', 'Very Good', 'Premium', 'Ideal'],ordered=True).cat.codes
df['clarity']=df.clarity.astype('category').cat.reorder_categories(['I1', 'SI2', 'SI1', 'VS2', 'VS1', 'VVS2', 'VVS1', 'IF'],ordered=True).cat.codes
df.head()
>>>
> carat cut clarity price
0 0.23 4 1 326
1 0.21 3 2 326
2 0.23 1 4 327
3 0.29 3 3 334
4 0.31 1 1 335
#利用replace()函数
cut_cat=['Fair', 'Good', 'Very Good', 'Premium', 'Ideal']
df.cut=df.cut.replace(cut_cat,np.arange(len(cut_cat)))
clarity_cut=['I1', 'SI2', 'SI1', 'VS2', 'VS1', 'VVS2', 'VVS1', 'IF']
df.clarity=df.clarity.replace(clarity_cut,np.arange(len(clarity_cut)))
df.head()
>>>
> carat cut clarity price
0 0.23 4 1 326
1 0.21 3 2 326
2 0.23 1 4 327
3 0.29 3 3 334
4 0.31 1 1 335
4 .使用pd.cut()和pd.qcut()可以完成数值型到类别型特征的转换,关键在于切割点bins的选取。
#pd.cut()函数
df['cat1']=pd.cut(df.price/df.carat,bins=[-np.infty,1000, 3500, 5500, 18000,np.infty],labels=['Very Low', 'Low', 'Mid', 'High', 'Very High'])
#pd.qcut()函数
df['cat2']=pd.qcut(df.price/df.carat,q=[0, 0.2, 0.4, 0.6, 0.8, 1],labels=['Very Low', 'Low', 'Mid', 'High', 'Very High'])
df.head()
>>>
> carat cut clarity price cat1 cat2
0 0.23 Ideal SI2 326 Low Very Low
1 0.21 Premium SI1 326 Low Very Low
2 0.23 Good VS1 327 Low Very Low
3 0.29 Premium VS2 334 Low Very Low
4 0.31 Good SI2 335 Low Very Low