前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python-for-data-Category

python-for-data-Category

作者头像
皮大大
发布2021-03-01 14:43:27
1K0
发布2021-03-01 14:43:27
举报

Python-for-data-分类Category

本文中介绍的是分类数据\color{red}{category}的使用

分裂数据Categorical

代码语言:javascript
复制
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
使用背景和目标

一个列中经常会包含重复值,这些重复值是一个小型的不同值的集合。

unique()value_counts()能够从数组中提取到不同的值并分别计算它们的频率

代码语言:javascript
复制
values = pd.Series(["apple","orange","apple","apple"] * 2)
values
代码语言:javascript
复制
0     apple
1    orange
2     apple
3     apple
4     apple
5    orange
6     apple
7     apple
dtype: object
代码语言:javascript
复制
pd.unique(values)   # 查看不同的取值情况
代码语言:javascript
复制
array(['apple', 'orange'], dtype=object)
代码语言:javascript
复制
pd.value_counts(values)  # 查看每个值的个数
代码语言:javascript
复制
apple     6
orange    2
dtype: int64
维度表

维度表包含了不同的值,将主要观测值存储为引用维度表的整数键

代码语言:javascript
复制
values = pd.Series([0,1,0,0] * 2)

dim = pd.Series(["apple","orange"])
代码语言:javascript
复制
values
代码语言:javascript
复制
0    0
1    1
2    0
3    0
4    0
5    1
6    0
7    0
dtype: int64
代码语言:javascript
复制
dim
代码语言:javascript
复制
0     apple
1    orange
dtype: object
take方法-分类(字典编码展现)

不同值的数组被称之为数据的类别、字典或者层级

代码语言:javascript
复制
dim.take(values)
代码语言:javascript
复制
0     apple
1    orange
0     apple
0     apple
0     apple
1    orange
0     apple
0     apple
dtype: object

使用Categorical类型

代码语言:javascript
复制
fruits = ["apple","orange","apple","apple"] * 2
N = len(fruits)
df = pd.DataFrame({"fruit":fruits,  # 指定每列的取值内容
                  "basket_id":np.arange(N),
                  "count":np.random.randint(3,15,size=N),
                  "weight":np.random.uniform(0,4,size=N)},
                 columns=["basket_id","fruit","count","weight"])  # 4个属性值
代码语言:javascript
复制
df

.dataframe tbody tr th:only-of-type { vertical-align: middle; } <pre><code>.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; } </code></pre>

basket_id

fruit

count

weight

0

0

apple

14

0.569836

1

1

orange

12

1.239917

2

2

apple

13

2.587898

3

3

apple

10

2.768119

4

4

apple

6

3.867747

5

5

orange

8

0.194426

6

6

apple

12

2.686968

7

7

apple

9

0.113434

代码语言:javascript
复制
df["fruit"]
代码语言:javascript
复制
0     apple
1    orange
2     apple
3     apple
4     apple
5    orange
6     apple
7     apple
Name: fruit, dtype: object
如何生成Categorical实例
代码语言:javascript
复制
fruit_cat = df["fruit"].astype("category")  # 调用函数改变
fruit_cat   # 变成pd.Categorical的实例
代码语言:javascript
复制
0     apple
1    orange
2     apple
3     apple
4     apple
5    orange
6     apple
7     apple
Name: fruit, dtype: category
Categories (2, object): [apple, orange]
代码语言:javascript
复制
c = fruit_cat.values
c
代码语言:javascript
复制
[apple, orange, apple, apple, apple, orange, apple, apple]
Categories (2, object): [apple, orange]
两个属性:categories + codes
代码语言:javascript
复制
print(c.categories)
print("-----")
print(c.codes)
代码语言:javascript
复制
Index(['apple', 'orange'], dtype='object')
-----
[0 1 0 0 0 1 0 0]
代码语言:javascript
复制
# 将DF的一列转成Categorical对象
df["fruit"] = df["fruit"].astype("category")
代码语言:javascript
复制
df.fruit
代码语言:javascript
复制
0     apple
1    orange
2     apple
3     apple
4     apple
5    orange
6     apple
7     apple
Name: fruit, dtype: category
Categories (2, object): [apple, orange]
从其他序列生成pd.Categorical对象
代码语言:javascript
复制
my_categories = pd.Categorical(['foo','bar','baz','foo','bar'])
my_categories
代码语言:javascript
复制
[foo, bar, baz, foo, bar]
Categories (3, object): [bar, baz, foo]
已知分类编码数据的情况:from_codes
代码语言:javascript
复制
categories = ["foo","bar","baz"]
codes = [0,1,0,0,1,0,1,0]
my_code = pd.Categorical.from_codes(codes,categories)
代码语言:javascript
复制
my_code
代码语言:javascript
复制
[foo, bar, foo, foo, bar, foo, bar, foo]
Categories (3, object): [foo, bar, baz]
显式指定分类顺序:ordered = True

如果不指定顺序,分类转换是无序的。我们可以自己显式地指定

代码语言:javascript
复制
ordered_cat = pd.Categorical.from_codes(codes,categories  # 指定分类用的数据
                                       ,ordered=True)
ordered_cat
代码语言:javascript
复制
[foo, bar, foo, foo, bar, foo, bar, foo]
Categories (3, object): [foo < bar < baz]
未排序的实例通过as_ordered排序
代码语言:javascript
复制
# 未排序的实例通过as_ordered来进行排序
my_categories.as_ordered()
代码语言:javascript
复制
[foo, bar, baz, foo, bar]
Categories (3, object): [bar < baz < foo]

Categorical对象来进行计算

代码语言:javascript
复制
np.random.seed(12345)  # 设置随机种子
draws = np.random.randn(1000)
draws[:5]
代码语言:javascript
复制
array([-0.20470766,  0.47894334, -0.51943872, -0.5557303 ,  1.96578057])
qcut()函数-四分位数
代码语言:javascript
复制
# 计算四位分箱
bins = pd.qcut(draws,4)
bins
代码语言:javascript
复制
[(-0.684, -0.0101], (-0.0101, 0.63], (-0.684, -0.0101], (-0.684, -0.0101], (0.63, 3.928], ..., (-0.0101, 0.63], (-0.684, -0.0101], (-2.9499999999999997, -0.684], (-0.0101, 0.63], (0.63, 3.928]]
Length: 1000
Categories (4, interval[float64]): [(-2.9499999999999997, -0.684] < (-0.684, -0.0101] < (-0.0101, 0.63] < (0.63, 3.928]]
四分位数名称 labels
代码语言:javascript
复制
bins = pd.qcut(draws,4,labels=["Q1","Q2","Q3","Q4"])
bins
代码语言:javascript
复制
[Q2, Q3, Q2, Q2, Q4, ..., Q3, Q2, Q1, Q3, Q4]
Length: 1000
Categories (4, object): [Q1 < Q2 < Q3 < Q4]
代码语言:javascript
复制
bins.codes[:10]
代码语言:javascript
复制
array([1, 2, 1, 1, 3, 3, 2, 2, 3, 3], dtype=int8)
结合groupby提取汇总信息
代码语言:javascript
复制
bins = pd.Series(bins, name="quartile")
results = (pd.Series(draws)
          .groupby(bins)
          .agg(["count","min","max"]).reset_index()
          )
results

.dataframe tbody tr th:only-of-type { vertical-align: middle; } <pre><code>.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; } </code></pre>

quartile

count

min

max

0

Q1

250

-2.949343

-0.685484

1

Q2

250

-0.683066

-0.010115

2

Q3

250

-0.010032

0.628894

3

Q4

250

0.634238

3.927528

代码语言:javascript
复制
results["quartile"]  # 保留原始中的分类信息
代码语言:javascript
复制
0    Q1
1    Q2
2    Q3
3    Q4
Name: quartile, dtype: category
Categories (4, object): [Q1 < Q2 < Q3 < Q4]

分类提高性能

如果在特定的数据集上做了大量的数据分析,将数据转成分类数据有大大提高性能

代码语言:javascript
复制
N = 10000000
draws = pd.Series(np.random.randn(N))
labels = pd.Series(["foo","bar","baz","qux"] * (N // 4))
labels
代码语言:javascript
复制
0          foo
1          bar
2          baz
3          qux
4          foo
          ...
9999995    qux
9999996    foo
9999997    bar
9999998    baz
9999999    qux
Length: 10000000, dtype: object
转成分类数据
代码语言:javascript
复制
# 转成分类数据
categories = labels.astype("category")
categories
代码语言:javascript
复制
0          foo
1          bar
2          baz
3          qux
4          foo
          ...
9999995    qux
9999996    foo
9999997    bar
9999998    baz
9999999    qux
Length: 10000000, dtype: category
Categories (4, object): [bar, baz, foo, qux]
内存比较
代码语言:javascript
复制
labels.memory_usage()
代码语言:javascript
复制
80000128
代码语言:javascript
复制
categories.memory_usage()
代码语言:javascript
复制
10000320
分类转换的开销
代码语言:javascript
复制
%time _ = labels.astype("category")
代码语言:javascript
复制
CPU times: user 374 ms, sys: 34.8 ms, total: 409 ms
Wall time: 434 ms

分类方法

代码语言:javascript
复制
s = pd.Series(["a","b","c","d"] * 2)
cat_s = s.astype("category")
cat_s
代码语言:javascript
复制
0    a
1    b
2    c
3    d
4    a
5    b
6    c
7    d
dtype: category
Categories (4, object): [a, b, c, d]
cat属性

特殊属性cat提供了对分类方法的访问

  • codes
  • categories
  • set_categories
代码语言:javascript
复制
cat_s.cat.codes
代码语言:javascript
复制
0    0
1    1
2    2
3    3
4    0
5    1
6    2
7    3
dtype: int8
代码语言:javascript
复制
cat_s.cat.categories
代码语言:javascript
复制
Index(['a', 'b', 'c', 'd'], dtype='object')
数据的实际类别超出给定的个数
代码语言:javascript
复制
actual_categories = ["a","b","c","d","e"]
cat_s2 = cat_s.cat.set_categories(actual_categories)
cat_s2
代码语言:javascript
复制
0    a
1    b
2    c
3    d
4    a
5    b
6    c
7    d
dtype: category
Categories (5, object): [a, b, c, d, e]
代码语言:javascript
复制
cat_s2.value_counts()
代码语言:javascript
复制
d    2
c    2
b    2
a    2
e    0
dtype: int64
去除不在数据中的类别
代码语言:javascript
复制
cat_s3 = cat_s[cat_s.isin(["a","b"])]
cat_s3
代码语言:javascript
复制
0    a
1    b
4    a
5    b
dtype: category
Categories (4, object): [a, b, c, d]
代码语言:javascript
复制
# c、d没有出现,直接删除
cat_s3.cat.remove_unused_categories()
代码语言:javascript
复制
0    a
1    b
4    a
5    b
dtype: category
Categories (2, object): [a, b]

如何创建虚拟变量:get_dummies()

在机器学习或统计数据中,通常需要将分类数据转成虚拟变量,也称之为one-hot编码

代码语言:javascript
复制
cat_s = pd.Series(["a","b","c","d"] * 2, dtype="category")
cat_s
代码语言:javascript
复制
0    a
1    b
2    c
3    d
4    a
5    b
6    c
7    d
dtype: category
Categories (4, object): [a, b, c, d]
代码语言:javascript
复制
pd.get_dummies(cat_s)

.dataframe tbody tr th:only-of-type { vertical-align: middle; } <pre><code>.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; } </code></pre>

a

b

c

d

0

1

0

0

0

1

0

1

0

0

2

0

0

1

0

3

0

0

0

1

4

1

0

0

0

5

0

1

0

0

6

0

0

1

0

7

0

0

0

1

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-5-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 分裂数据Categorical
    • 使用背景和目标
      • 维度表
        • take方法-分类(字典编码展现)
        • 使用Categorical类型
          • 如何生成Categorical实例
            • 两个属性:categories + codes
              • 从其他序列生成pd.Categorical对象
                • 已知分类编码数据的情况:from_codes
                  • 显式指定分类顺序:ordered = True
                    • 未排序的实例通过as_ordered排序
                    • Categorical对象来进行计算
                      • qcut()函数-四分位数
                        • 四分位数名称 labels
                          • 结合groupby提取汇总信息
                          • 分类提高性能
                            • 转成分类数据
                              • 内存比较
                                • 分类转换的开销
                                • 分类方法
                                  • cat属性
                                    • 数据的实际类别超出给定的个数
                                      • 去除不在数据中的类别
                                      • 如何创建虚拟变量:get_dummies()
                                      领券
                                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档