Python Pandas 第8章 分类数据

>>> import pandas as pd
>>> import numpy as np
>>> df = pd.read_csv('data/table.csv')
>>> df.head()
  School	Class	ID	Gender	Address	Height	Weight	Math	Physics
0	S_1	C_1	1101	M	street_1	173	63	34.0	A+
1	S_1	C_1	1102	F	street_2	192	73	32.5	B+
2	S_1	C_1	1103	M	street_2	186	82	87.2	B+
3	S_1	C_1	1104	F	street_2	167	81	80.4	B-
4	S_1	C_1	1105	F	street_4	159	64	84.8	B+

一、category的创建及其性质

1. 分类变量的创建

(a)用Series创建

>>> pd.Series(["a", "b", "c", "a"], dtype="category")
0    a
1    b
2    c
3    a
dtype: category
Categories (3, object): [a, b, c]

(b)对DataFrame指定类型创建

>>> temp_df = pd.DataFrame({'A':pd.Series(["a", "b", "c", "a"], dtype="category"),'B':list('abcd')})
>>> temp_df.dtypes
A    category
B      object
dtype: object

(c)利用内置Categorical类型创建

>>> cat = pd.Categorical(["a", "b", "c", "a"], categories=['a','b','c'])
>>> pd.Series(cat)
0    a
1    b
2    c
3    a
dtype: category
Categories (3, object): [a, b, c]

(d)利用cut函数创建

默认使用区间类型为标签

>>> pd.cut(np.random.randint(0,60,5), [0,10,30,60])
[(10, 30], (0, 10], (10, 30], (30, 60], (30, 60]]
Categories (3, interval[int64]): [(0, 10] < (10, 30] < (30, 60]]

可指定字符为标签

>>> pd.cut(np.random.randint(0,60,5), [0,10,30,60], right=False, labels=['0-10','10-30','30-60'])
[10-30, 30-60, 30-60, 10-30, 30-60]
Categories (3, object): [0-10 < 10-30 < 30-60]

2. 分类变量的结构

一个分类变量包括三个部分,元素值(values)、分类类别(categories)、是否有序(order
从上面可以看出,使用cut函数创建的分类变量默认为有序分类变量
下面介绍如何获取或修改这些属性

(a)describe方法

该方法描述了一个分类序列的情况,包括非缺失值个数、元素值类别数(不是分类类别数)、最多次出现的元素及其频数

>>> s = pd.Series(pd.Categorical(["a", "b", "c", "a",np.nan], categories=['a','b','c','d']))
>>> s.describe()
count     4
unique    3
top       a
freq      2
dtype: object

(b)categories和ordered属性

查看分类类别和是否排序

>>> s.cat.categories
Index(['a', 'b', 'c', 'd'], dtype='object')

>>> s.cat.ordered
False

3. 类别的修改

(a)利用set_categories修改

修改分类,但本身值不会变化

>>> s = pd.Series(pd.Categorical(["a", "b", "c", "a",np.nan], categories=['a','b','c','d']))
>>> s.cat.set_categories(['new_a','c'])
0    NaN
1    NaN
2      c
3    NaN
4    NaN
dtype: category
Categories (2, object): [new_a, c]

(b)利用rename_categories修改

需要注意的是该方法会把值和分类同时修改

>>> s = pd.Series(pd.Categorical(["a", "b", "c", "a",np.nan], categories=['a','b','c','d']))
>>> s.cat.rename_categories(['new_%s'%i for i in s.cat.categories])
0    new_a
1    new_b
2    new_c
3    new_a
4      NaN
dtype: category
Categories (4, object): [new_a, new_b, new_c, new_d]

利用字典修改值

>>> s.cat.rename_categories({'a':'new_a','b':'new_b'})
0    new_a
1    new_b
2        c
3    new_a
4      NaN
dtype: category
Categories (4, object): [new_a, new_b, c, d]

(c)利用add_categories添加

>>> s = pd.Series(pd.Categorical(["a", "b", "c", "a",np.nan], categories=['a','b','c','d']))
>>> s.cat.add_categories(['e'])
0      a
1      b
2      c
3      a
4    NaN
dtype: category
Categories (5, object): [a, b, c, d, e]

(d)利用remove_categories移除

>>> s = pd.Series(pd.Categorical(["a", "b", "c", "a",np.nan], categories=['a','b','c','d']))
>>> s.cat.remove_categories(['d'])
0      a
1      b
2      c
3      a
4    NaN
dtype: category
Categories (3, object): [a, b, c]

(e)删除元素值未出现的分类类型

>>> s = pd.Series(pd.Categorical(["a", "b", "c", "a",np.nan], categories=['a','b','c','d']))
>>> s.cat.remove_unused_categories()
0      a
1      b
2      c
3      a
4    NaN
dtype: category
Categories (3, object): [a, b, c]

二、分类变量的排序

前面提到,分类数据类型被分为有序和无序,这非常好理解,例如分数区间的高低是有序变量,考试科目的类别一般看做无序变量

1. 序的建立

(a)一般来说会将一个序列转为有序变量,可以利用as_ordered方法

>>> s = pd.Series(["a", "d", "c", "a"]).astype('category').cat.as_ordered()
>>> s
0    a
1    d
2    c
3    a
dtype: category
Categories (3, object): [a < c < d]

退化为无序变量,只需要使用as_unordered

>>> s.cat.as_unordered()
0    a
1    d
2    c
3    a
dtype: category
Categories (3, object): [a, c, d]

(b)利用set_categories方法中的order参数

>>> pd.Series(["a", "d", "c", "a"]).astype('category').cat.set_categories(['a','c','d'],ordered=True)
0    a
1    d
2    c
3    a
dtype: category
Categories (3, object): [a < c < d]

(c)利用reorder_categories方法

这个方法的特点在于,新设置的分类必须与原分类为同一集合

>>> s = pd.Series(["a", "d", "c", "a"]).astype('category')
>>> s.cat.reorder_categories(['a','c','d'],ordered=True)
0    a
1    d
2    c
3    a
dtype: category
Categories (3, object): [a < c < d]
>>> #s.cat.reorder_categories(['a','c'],ordered=True) #报错
>>> #s.cat.reorder_categories(['a','c','d','e'],ordered=True) #报错

2. 排序

先前在第1章介绍的值排序和索引排序都是适用的

>>> s = pd.Series(np.random.choice(['perfect','good','fair','bad','awful'],50)).astype('category')
>>> s.cat.set_categories(['perfect','good','fair','bad','awful'][::-1],ordered=True).head()
0       good
1       fair
2        bad
3    perfect
4    perfect
dtype: category
Categories (5, object): [awful < bad < fair < good < perfect]

>>> s.sort_values(ascending=False).head()
29    perfect
17    perfect
31    perfect
3     perfect
4     perfect
dtype: category
Categories (5, object): [awful, bad, fair, good, perfect]

>>> df_sort = pd.DataFrame({'cat':s.values,'value':np.random.randn(50)}).set_index('cat')
>>> df_sort.head()
            value
cat	
good    -1.746975
fair     0.836732
bad      0.094912
perfect -0.724338
perfect -1.456362

>>> df_sort.sort_index().head()
          value
cat	
awful  0.245782
awful  0.063991
awful  1.541862
awful -0.062976
awful  0.472542

三、分类变量的比较操作

1. 与标量或等长序列的比较

(a)标量比较

>>> s = pd.Series(["a", "d", "c", "a"]).astype('category')
>>> s == 'a'
0     True
1    False
2    False
3     True
dtype: bool

(b)等长序列比较

>>> s == list('abcd')
0     True
1    False
2     True
3    False
dtype: bool

2. 与另一分类变量的比较

(a)等式判别(包含等号和不等号)

两个分类变量的等式判别需要满足分类完全相同

>>> s = pd.Series(["a", "d", "c", "a"]).astype('category')
>>> s == s
0    True
1    True
2    True
3    True
dtype: bool

>>> s != s
0    False
1    False
2    False
3    False
dtype: bool

>> s_new = s.cat.set_categories(['a','d','e'])
>>> #s == s_new #报错

(b)不等式判别(包含>=,<=,<,>)

两个分类变量的不等式判别需要满足两个条件:① 分类完全相同 ② 排序完全相同

>>> s = pd.Series(["a", "d", "c", "a"]).astype('category')
>>> #s >= s #报错
>>> s = pd.Series(["a", "d", "c", "a"]).astype('category').cat.reorder_categories(['a','c','d'],ordered=True)
>>> s >= s
0    True
1    True
2    True
3    True
dtype: bool

相关文章
Python Pandas 第1章 基础
Python Pandas 第2章 索引
Python Pandas 第3章 分组
Python Pandas 第4章 变形
Python Pandas 第5章 合并
Python Pandas 第6章 缺少数据
Python Pandas 第7章 文本数据
Python Pandas 第8章 分类数据
Python Pandas 第9章 时序数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值