前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >pandas系列8-分类类型categories

pandas系列8-分类类型categories

作者头像
皮大大
发布2021-03-02 15:24:24
3.3K0
发布2021-03-02 15:24:24
举报

分类

分类的目的是提高性能和内存的使用率

用整数表示的方法称为分类或者字典编码表示法,不同值的数组称为分类、字典或者数据集。

创建分类
  • take方法存储原始字符串Series
  • 直接创建分类:pd.Categorical(data)
  • 转变成类:df.astype('category')
  • 分类对象属性
    • codes
    • categories
分类计算
  • 面元函数qcut函数返回类Categories对象:pd.qcut(draws, 4)
  • 通过labels标签实现汇总
  • groupby提取汇总信息
代码语言:javascript
复制
import numpy as np
import pandas as pd
from pandas import Series, DataFrame
代码语言:javascript
复制
results = (pd.Series(draws)
    .groupby(bins)
    .agg(['count', 'min', 'max'])
    .reset_index())
分类方法
  • memory_usage():查看内存
  • cat():提供入口
    • pd.cat.categories
    • pd.cat.codes
  • value_counts():查看具体分类
  • 创建虚拟变量,用0/1组成的矩阵
代码语言:javascript
复制
values = pd.Series(['apple', 'orange', 'apple', 'apple'] * 2)
pd.unique(values)  # 选取唯一值
代码语言:javascript
复制
array(['apple', 'orange'], dtype=object)
代码语言:javascript
复制
pd.value_counts(values)   # 计算每个值出现的频率
代码语言:javascript
复制
apple     6
orange    2
dtype: int64

数据系统使用包含不同值的维表Dimension Table ,将主要的参数存储为引用维表整数键

  • take()方法:分类
去重显示
代码语言:javascript
复制
values = pd.Series([0, 1, 0, 0] * 2)
dim = pd.Series(['apple', 'orange'])
代码语言:javascript
复制
print(values)
print(dim)
代码语言:javascript
复制
0    0
1    1
2    0
3    0
4    0
5    1
6    0
7    0
dtype: int64
0     apple
1    orange
dtype: object
代码语言:javascript
复制
dim.take(values)   # take方法
代码语言:javascript
复制
0     apple
1    orange
0     apple
0     apple
0     apple
1    orange
0     apple
0     apple
dtype: object

pandas分类类型

代码语言:javascript
复制
fruits = ['apple', 'orange', 'apple', 'apple'] * 2
N = len(fruits)
代码语言:javascript
复制
df = pd.DataFrame({'fruit': fruits,
                   'basket_id': np.arange(N),
                   'count': np.random.randint(3, 15, size=N),   # 生成3-15随机整数
                   'weight': np.random.uniform(0, 4, size=N)},  # 生成0-4的数 
                  columns=['basket_id', 'fruit', 'count', 'weight'])
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

12

1.550912

1

1

orange

6

3.457292

2

2

apple

3

3.986303

3

3

apple

7

0.955448

4

4

apple

9

1.912784

5

5

orange

6

1.405372

6

6

apple

11

2.882363

7

7

apple

12

2.137783

转成分类

通过astype(‘category’)将某个属性转成分类类型

代码语言:javascript
复制
# 转换成分类
fruit_cat = df['fruit'].astype('category')
fruit_cat
代码语言: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
复制
print(type(fruit_cat))   # S型数据
<class 'pandas.core.series.Series'>
代码语言:javascript
复制
c = fruit_cat.valuest
type(c)  # c是⼀个pandas.Categorical实例
代码语言:javascript
复制
pandas.core.arrays.categorical.Categorical
两个属性值codes 和 categories
代码语言:javascript
复制
# 分类对象有categories和codes属性
print(c.categories)  # categories是具体的分类
print(c.codes)   # codes是里面的0、1值
代码语言:javascript
复制
Index(['apple', 'orange'], dtype='object')
[0 1 0 0 0 1 0 0]
代码语言: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

12

1.550912

1

1

orange

6

3.457292

2

2

apple

3

3.986303

3

3

apple

7

0.955448

4

4

apple

9

1.912784

5

5

orange

6

1.405372

6

6

apple

11

2.882363

7

7

apple

12

2.137783

代码语言:javascript
复制
# 将列转换成分类
df['fruit'] = df['fruit'].astype("category")
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]
代码语言:javascript
复制
# 通过Python其他序列创建分类
my_categories = pd.Categorical(['foo', 'bar', 'baz', 'foo', 'bar'])
my_categories
代码语言:javascript
复制
[foo, bar, baz, foo, bar]
Categories (3, object): [bar, baz, foo]
代码语言:javascript
复制
# 通过from_codes构建分类
categories = ['foo', 'bar', 'baz']
codes = [0, 1, 2, 0, 0, 1]
my_cats_2 = pd.Categorical.from_codes(codes, categories)  # from_codes构造器
my_cats_2
代码语言:javascript
复制
[foo, bar, baz, foo, foo, bar]
Categories (3, object): [foo, bar, baz]
代码语言:javascript
复制
# 无序的分类实例通过as_ordered进行排序
my_cats_2.as_ordered()
代码语言:javascript
复制
[foo, bar, baz, foo, foo, bar]
Categories (3, object): [foo < bar < baz]
代码语言:javascript
复制
# 创建分类的实例直接指定顺序: ordered=True
ordered_cat = pd.Categorical.from_codes(codes, categories,
                                        ordered=True)
ordered_cat
代码语言:javascript
复制
[foo, bar, baz, foo, foo, bar]
Categories (3, object): [foo < bar < baz]

分类计算

重点关注pandas中的Categorical类。通过使用pandas.qcut面元函数,返回pandas.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])
代码语言: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]]
使用lables参数来qcut
代码语言: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)
代码语言:javascript
复制
# groupby 提取汇总信息
bins = pd.Series(bins, name="quratile")
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>

quratile

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
复制
bins = pd.Series(bins, name="quratile")
result = (pd.Series(draws)
          .groupby(bins)
          .agg(["count", "min", "max"]))
result

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

count

min

max

quratile

Q1

250

-2.949343

-0.685484

Q2

250

-0.683066

-0.010115

Q3

250

-0.010032

0.628894

Q4

250

0.634238

3.927528

代码语言:javascript
复制
results["quratile"]
代码语言:javascript
复制
0    Q1
1    Q2
2    Q3
3    Q4
Name: quratile, dtype: category
Categories (4, object): [Q1 < Q2 < Q3 < Q4]

分类提高性能

  • 使用DF的列分类占用内存少
  • memory_usage():查看内存
代码语言:javascript
复制
N = 10000000
draws = pd.Series(np.random.randn(N))
labels = pd.Series(['foo', 'bar', 'baz', 'qux'] * (N // 4))
代码语言:javascript
复制
categories = labels.astype("category")
categories.memory_usage()  # 分类占用内存少
代码语言:javascript
复制
10000272
代码语言:javascript
复制
labels.memory_usage()   # 非分类占用内存多
代码语言:javascript
复制
80000080
代码语言:javascript
复制
%time _ = labels.astype('category')
代码语言:javascript
复制
Wall time: 444 ms

分类方法

  • 先使用分类入口:cat方法;再使用codes,categories方法
    • cat.codes
    • cat.categories
  • set_categories:解决超出给定的数据集个数
  • value_counts():查看分类的个数
  • remove_unused_categories():删除没有看到的数据
  • 常用方法汇总

方法

作用

add_categories

已存在分类的后面直接添加

as_ordered

使分类有序

as_unordered

使分类无序

remove_categories

移除分类,设置移除值为null

remove_unused_categories

移除任意不出现在数据中的分类值

set_categories

用指定的新分类的名字来替换分类,可以添加或者删除分类

代码语言: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]
代码语言:javascript
复制
# cat属性提供分类方法的入口
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
复制
# 实际分类超出给定数据集中的个数,通过set_catgories实现
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_s.value_counts()
代码语言:javascript
复制
d    2
c    2
b    2
a    2
dtype: int64
代码语言:javascript
复制
cat_s2.value_counts()
代码语言:javascript
复制
d    2
c    2
b    2
a    2
e    0
dtype: int64
代码语言:javascript
复制
#  remove_unused_categories()
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
复制
cat_s.isin(['a', 'b'])
代码语言:javascript
复制
0     True
1     True
2    False
3    False
4     True
5     True
6    False
7    False
dtype: bool
代码语言:javascript
复制
# 查看分类,变成2个
cat_s3.cat.remove_unused_categories()
代码语言:javascript
复制
0    a
1    b
4    a
5    b
dtype: category
Categories (2, object): [a, b]

创建虚拟变量

虚拟变量创建的过程实际上是将各个分类的标签看成是列属性,存在的数据则是1,不存在则是0,创建0/1矩阵

  • 分类数据转成虚拟变量:one-hot编码
  • 创建值为0或者1的DF数据
  • pd.get_dummies()
代码语言:javascript
复制
cat_s = pd.Series(['a', 'b', 'c', 'd'] * 2, dtype='category')
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

代码语言:javascript
复制
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]
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-10-21,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 分类
    • 创建分类
      • 分类计算
        • 分类方法
          • 去重显示
          • pandas分类类型
            • 转成分类
              • 两个属性值codes 和 categories
              • 分类计算
                • 使用lables参数来qcut
                • 分类提高性能
                • 分类方法
                • 创建虚拟变量
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档