Pandas学习笔记(八)—— Pandas分类数据

前导


更多文章代码详情可查看博主个人网站:https://www.iwtmbtly.com/


导入需要使用的库和文件:

>>> 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. 用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']

2. 对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

3. 利用内置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']

4. 利用cut函数创建

默认使用区间类型为标签:

>>> pd.cut(np.random.randint(0,60,5), [0,10,30,60])
[(0, 10], (10, 30], (10, 30], (10, 30], (30, 60]]
Categories (3, interval[int64, right]): [(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'])
['30-60', '30-60', '30-60', '10-30', '30-60']
Categories (3, object): ['0-10' < '10-30' < '30-60']

(二)分类变量的结构

一个分类变量包括三个部分,元素值(values)、分类类别(categories)、是否有序(order)

从上面可以看出,使用cut函数创建的分类变量默认为有序分类变量

下面介绍如何获取或修改这些属性

1. 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

2. categories和ordered属性

查看分类类别以及是否排序:

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

(三)类别的修改

1. 利用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']

2. 利用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']

3. 利用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']

4. 利用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']

5. 删除元素值未出现的分类类型

>>> 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. 一般来说会将一个序列转为有序变量,可以利用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']

2. 利用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']

3. 利用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) # 报错

(二)排序

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     good
2     fair
3    awful
4     good
dtype: category
Categories (5, object): ['awful' < 'bad' < 'fair' < 'good' < 'perfect']
>>> s.sort_values(ascending=False).head()
49    perfect
41    perfect
38    perfect
34    perfect
31    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  -0.492898
good  -0.800566
fair   0.355032
awful  0.299062
good  -2.321767
>>> df_sort.sort_index().head()
          value
cat
awful  0.435638
awful  1.912790
awful -0.204264
awful  0.299062
awful -0.585013

三、分类变量的比较操作

(一)与标量或等长序列的比较

1. 标量比较

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

2. 等长序列比较

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

(二)与另一分类变量的比较

1. 等式判别(包含等号和不等号)

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

>>> 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	# 报错
    raise TypeError(msg)
TypeError: Categoricals can only be compared if 'categories' are the same.

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

两个分类变量的不等式判别需要满足两个条件:

  • 分类完全相同

  • 排序完全相同

>>> s = pd.Series(["a", "d", "c", "a"]).astype('category')
>>> # s >= s # 报错
 raise TypeError(
TypeError: Unordered Categoricals can only compare equality or not
>>> 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

猜你喜欢

转载自blog.csdn.net/qq_43300880/article/details/125029001