loading

Pandas - Categorical 数据类型带来的效率和作用

描述

  • 在遇到量大且重复的数据时,将其某 Series 转换为 Categorical 类型,再结合 groupby 函处理数据效率会更高。
  • 给 Series 打上标记,标注排列顺序,结合 sort_values 函数将 DataFrame 进行重新排序。

自定义排序

Categorical 可以按照特定的顺序进行排序。在定义 Categorical 类型时,你可以指定一个类别的顺序,这被称为类别的有序性(orderliness)。如果你没有指定顺序,类别将按照它们在数据中出现的顺序进行排序。

要按照特定顺序排序 Categorical 数据,你需要在创建 Categorical 类型的时候指定 categories 参数来定义顺序,并设置 ordered=True 来表示这个顺序是有意义的。

file:[例1]
import pandas as pd

cat_type = pd.CategoricalDtype(categories=['low', 'medium', 'high'], ordered=True)
ser = pd.Series(['low', 'medium', 'high', 'medium', 'low'], dtype=cat_type, name='quality')
df = pd.DataFrame(ser).sort_values(by=['quality'])

打印结果:

file:[打印结果2]
  quality
0     low
4     low
1  medium
3  medium
2    high

结合 groupby

例如,假设你有一个包含商品信息的 DataFrame,并且其中有一列是商品类型,类型的数量相对于数据集是有限的。首先,你可以将商品类型列转换为 Categorical 类型:

file:[例2]
import pandas as pd

df = pd.DataFrame({
    'product_type': ['apple', 'banana', 'cherry', 'apple'],
    'price': [12, 13, 14, 12.5]
})

df['product_type'] = df['product_type'].astype('category')
average_price_per_type = df.groupby('product_type', observed=True)['price'].mean()

由于数据量少,似乎加不加 Categorical 类型都不影响。打印结果:

file:[打印结果1]
product_type
apple     12.25
banana    13.00
cherry    14.00
Name: price, dtype: float64

学习 Categorical

通过以上案例对该数据类型有了一个初步的了解,现在将系统性地进行学习。

Categorical 是给 Series 数据打上标记的一种数据类型,例如,一个调查问卷的答案(非常同意、同意、中立、不同意、非常不同意),就有5种标记。

给 Series 打上标记之后,不影响原有的数据内容,如下代码所示:

file:[例3]
cat_type = pd.CategoricalDtype(categories=['low', 'medium', 'high'], ordered=True)
ser = pd.Series(['low', 'medium', 'high', 'medium', 'low'], dtype=cat_type, name='quality')

"""打印结果
0       low
1    medium
2      high
3    medium
4       low
Name: quality, dtype: category
Categories (3, object): ['low' < 'medium' < 'high']
"""

Series 创建

dtype

file:[例4]
ser = pd.Series(["a", "b", "c", "a"], dtype="category")

"""打印结果
0    a
1    b
2    c
3    a
dtype: category
Categories (3, object): ['a', 'b', 'c']
"""

可以直接给 dtype 传递 CategoricalDtype 类型描述构建,如例3中所示。

astype

file:[例5]
df = pd.DataFrame({"A": ["a", "b", "c", "a"]})
df["B"] = df["A"].astype("category")

"""打印结果
   A  B
0  a  a
1  b  b
2  c  c
3  a  a
"""

可以直接给 astype 传递 CategoricalDtype 类型描述构建,如例3中所示。

Categorical 构造器

file:[例6]
raw_cat = pd.Categorical(
    ["a", "b", "c", "a"], categories=["b", "c", "d"], ordered=False
)
ser = pd.Series(raw_cat)

"""打印结果
0    NaN
1      b
2      c
3    NaN
dtype: category
Categories (3, object): ['b', 'c', 'd']
"""

DataFrame 创建

dtype

file:[例7]
df = pd.DataFrame({"A": list("abca"), "B": list("bccd")}, dtype="category")

"""df.dtypes 打印结果
A    category
B    category
dtype: object
"""

"""df 打印结果
   A  B
0  a  b
1  b  c
2  c  c
3  a  d
"""

可以直接给 dtype 传递 CategoricalDtype 类型描述构建,如例3中所示。

astype

file:[例8]
df = pd.DataFrame({"A": list("abca"), "B": list("bccd")})
df_cat = df.astype("category")

可以直接给 astype 传递 CategoricalDtype 类型描述构建,如例3中所示。

Categorical 构造器

file:[例9]
dfs = pd.DataFrame(
    {
        "A": pd.Categorical(
            list("bbeebbaa"),
            categories=["e", "a", "b"],
            ordered=True,
        ),
        "B": [1, 2, 1, 2, 2, 1, 2, 1],
    }
)

set_categories 和 reorder_categories

设置 category 排序规则。

file:[例10]
s = pd.Series(["one", "two", "-", "four"], dtype="category")
print(s.cat.reorder_categories(['one', 'two', 'four', '-', 'three']).sort_values(ascending=False), '\n')

"""报错
ValueError: items in new_categories are not the same as in old categories
"""

s = pd.Series(["one", "two", "-", "four"], dtype="category")
print(s.cat.reorder_categories(['one', 'two', 'four', '-']).sort_values(ascending=False), '\n')

"""
2       -
3    four
1     two
0     one
dtype: category
Categories (4, object): ['one', 'two', 'four', '-'] 
"""

如上例10示,reorder_categories 在 Series 中没有的就会报错,而 set_categories 则不会,没有的也会设置上。

posted @ 2024-01-09 16:15  Himmelbleu  阅读(7)  评论(0编辑  收藏  举报