Pandas的Categorical Data类型

pandas从0.15版开始提供分类数据类型,用于表示统计学里有限且唯一性数据集,例如描述个人信息的性别一般就男和女两个数据常用‘m‘和‘f‘来描述,有时也能对应编码映射为0和1。血型A、B、O和AB型等选择可以映射为0、1、2、3这四个数字分别代表各个血型。pandas里直接就有categorical类型,可以有效地对数据进行分组进行相应的汇总统计工作。

当DataFrame的某列(字段)上的数据值是都是某有限个数值的集合里的值的时候,例如:性别就男和女,有限且唯一。这列可以采用Categorical Data类型来存储、统计。

pandas的Categorical Data类型灵感来源于Data wareHorsing数据仓库里的维度表设计理念,即某列数据存储的不是数据本身,而是该数据对应的编码(有称为分类、字典编码) 这些编码比数据本身存储依赖的空间小,但能基于编码统计汇总的速度要比数据本身的存储、统计速度要快。

1 如何理解Categorical Data?

下面看一张某水果超市的供货商表(表1):

供货商 水果 价格
1 apple 5.20
2 pearl 3.50
3 orange 7.30
5 apple 5.00
6 orange 7.50
7 orange 7.30
9 apple 5.20
4 pearl 3.70
8 orange 7.30

第2列是各个水果供应商的能供应的水果类型,目前市场也就apple、pearl、orange三种水果可以买到,对于一个大超市而言可能这个表很长、有很多的水果供应商,假设有1亿条数据,那么数据存储所需空间主要浪费在水果名字上了,其他字段都是数值型的数据,而水果这一列是字符串型的,很占空间,如何能降低这张大表的存储空间浪费呢? 设计一个辅助的水果编码表(表2):

编码 水果
0 apple
1 pearl
2 orange

那么供应商的表就变为(表3):

供货商 水果 价格
1 0 5.20
2 1 3.50
3 2 7.30
5 0 5.00
6 2 7.50
7 2 7.30
9 0 5.20
4 1 3.70
8 2 7.30

变化后的表的数据存储所需的空间量就下来了。也就是说在供应商表里存储的不是水果名数据本身而是存储的水果对应的编码值(通常用整形数据)。可以查供应商表里水果的编码再查辅助的编码表找到水果名。这个水果的编码表在数据仓库里称为维度表(dimension tables)。 而pandas的categorical data的作用就是构建并依赖这个维度表,即例子里的水果编码表。pandas里维度表里记录着若干且唯一的几个分类,可以通过categorical数据的categories 属性获得而数据的所一一对应的编码可以通过codes获得。

编码 水果
0 apple
1 pearl
2 orange

当DataFrame里的某列数据采用categorical Data方式,那么这列数据的存储会大大降低。

import pandas as pd
import time

idx = [1,2,3,5,6,7,9,4,8]
name = ["apple","pearl","orange", "apple","orange","orange","apple","pearl","orange"]
price = [5.20,3.50,7.30,5.00,7.50,7.30,5.20,3.70,7.30]
df = pd.DataFrame({ "fruit": name , "price" : price}, index = idx)
print df,"\n"
print df.memory_usage(),"\n"
print df.dtypes
print "*" * 20
df[‘fruit‘] = df[‘fruit‘].astype(‘category‘)
print df
print df.memory_usage(),"\n"
print df.dtypes

程序的执行结果:

    fruit  price
1   apple    5.2
2   pearl    3.5
3  orange    7.3
5   apple    5.0
6  orange    7.5
7  orange    7.3
9   apple    5.2
4   pearl    3.7
8  orange    7.3 

fruit    72
price    72
dtype: int64 

fruit     object
price    float64
dtype: object
********************
    fruit  price
1   apple    5.2
2   pearl    3.5
3  orange    7.3
5   apple    5.0
6  orange    7.5
7  orange    7.3
9   apple    5.2
4   pearl    3.7
8  orange    7.3
fruit    33
price    72
dtype: int64 

fruit    category
price     float64
dtype: object

最初创建的DataFrame变量df的各个列的类型:

fruit     object
price    float64
dtype: object

经语句df[‘fruit‘] = df[‘fruit‘].astype(‘category‘)将fruit列由Series改为了category类型。

fruit    category
price     float64
dtype: object

请注意fruit列的类型的变化。正是因为fruit采用了category类型,其存储所需的空间由之前的

fruit    72
price    72
dtype: int64 

变为

fruit    33
price    72
dtype: int64 

即72变为33,变化了,尽管原始的DataFrame数据量不大,所以变化比率也不大。读者可以适当加大df的数据长度,可以看到很明显的存储容量的降低。

2 理解category

总结一下pandas的category数据,两次打印DataFrame数据df的结果都是一样的,但是第二次打印的df是其fruit列经语句df[‘fruit‘] = df[‘fruit‘].astype(‘category‘)改变了其数据类型已不是Series而是category类型,该列存储所需的内存使用容量大大降低。

import pandas as pd
import time

idx = [1,2,3,5,6,7,9,4,8]
name = ["apple","pearl","orange", "apple","orange","orange","apple","pearl","orange"]
price = [5.20,3.50,7.30,5.00,7.50,7.30,5.20,3.70,7.30]
#df = pd.DataFrame({ "fruit": name , "price" : price}, index = idx)
N = 1
df = pd.DataFrame({ "fruit": name * N, "price" : price * N}, index = idx * N)
df[‘fruit‘] = df[‘fruit‘].astype(‘category‘)
print df,"\n"
print "df.price.values\n", df.price.values,"\n"
print "df.fruit.values\n", df.fruit.values, "\n"
print "df.fruit.values.codes\n",df.fruit.values.codes, "\n"
print "df.fruit.values.categories\n",df.fruit.values.categories, "\n"

fruit列是category类型的,通过codes和categorie组合出fruit的values。

    fruit  price
1   apple    5.2
2   pearl    3.5
3  orange    7.3
5   apple    5.0
6  orange    7.5
7  orange    7.3
9   apple    5.2
4   pearl    3.7
8  orange    7.3 

df.price.values
[5.2 3.5 7.3 5.  7.5 7.3 5.2 3.7 7.3] 

df.fruit.values
[apple, pearl, orange, apple, orange, orange, apple, pearl, orange]
Categories (3, object): [apple, orange, pearl] 

df.fruit.values.codes
[0 2 1 0 1 1 0 2 1] 

df.fruit.values.categories
Index([u‘apple‘, u‘orange‘, u‘pearl‘], dtype=‘object‘) 

values对应于表1里的第2列即显示输出时“水果”,codes对应于表3的第2列即存储时“水果”列,categories对应于表2的“水果”列即有限唯一的一个集合。

3 总结

Categorical Data数据由codes和categories组成,categories是有限且唯一的分类集合,codes是原数据对应的分类的编码, Categorical Data不要求有限并唯一。

参考:

http://liao.cpython.org/pandas15/

原文地址:https://www.cnblogs.com/ratels/p/12248693.html

时间: 2024-08-01 09:36:57

Pandas的Categorical Data类型的相关文章

data类型的数据抽取年份或月份的函数

orcel里提供了按要求抽取data类型数据的函数,如,只需要年份,那么就可以用(A表里有一个data_str列,是data型.) select extract(month from data_str) newmonth from A where extract(year from data_str)='2015' group by extract(month from data_str); 上面做的就是将A表里的2015年的数据按照月份进行分组.

第五章 引用类型> Data类型

Data类型 data类型使用自UTC(国际协调时间)1970年 1 月 1 日午夜经过的毫秒数来保存日期. 创建一个日期对象: var now = new Date(); console.log(now); // Sun Jun 05 2016 17:43:32 GMT+0800 (中国标准时间) 创建日期对象的方法 Date.parse():接受一个表示日期的的字符串参数,EC5没有定义支持的日期合适,行为因现实而已. 浏览器设置为美国: ”月/日/年“             6/13/2

如何将查出的日期Data类型以Json格式输出到前端

方法一 在返回的实体的属性中加上注解 // 创建时间    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")    private Date createDate; 方法二 在Controller中注解一个@InitBinder,使用@ResponseBody时会将实体中的属性为Data类型的转换成JSON格式的日期 private static final SimpleDateFormat DATEFORMAT = new Simple

data类型的Url格式

所谓"data"类型的Url格式, 是在RFC2397中提出的,目的对于一些“小”的数据,可以在网页中直接嵌入,而不是从外部文件载入.例如对于img这个Tag,哪怕这个图片非常非常 的小,小到只有一个点,也是要从另外一个外部的图片文件例如gif文件中读入的,如果浏览器实现了data类型的Url格式,这个文件就可以直接从页面文 件内部读入了. data类型的Url格式早在1998年就提出了,时至今日,Firfox.Opera.Safari和Konqueror这些浏览器都已经支持,但是IE

“background-image:url(data:image”data类型的Url格式简介

所谓"data"类型的Url格式,是在RFC2397中 提出的,目的对于一些"小"的数据,可以在网页中直接嵌入,而不是从外部文件载入.例如对于img这个Tag,哪怕这个图片非常非常的小,小到只有一个 点,也是要从另外一个外部的图片文件例如gif文件中读入的,如果浏览器实现了data类型的Url格式,这个文件就可以直接从页面文件内部读入了. data类型的Url格式早在1998年就提出了,时至今日,Firfox.Opera.Safari和Konqueror这些浏览器都

pandas的Categorical方法

对于数据样本的标签,如果我们事先不知道这个样本有多少类别,那么可以对数据集的类别列进行统计,这时我们用pandas的Categorical方法就非常快的实现. 1.说明: 你的数据最好是一个series,之后,pd.Categorical(series),得到分类的对象,使用categories或者codes进行查看 2.操作: pd.Categorical( list ).codes 这样就可以直接得到原始数据的对应的序号列表,通过这样的处理可以将类别信息转化成数值信息 ,这样就可以应用到模型

pandas把'<m8[ns]'类型转换为int类型进行运算

工作中经常碰到两列数据为date类型,当这两列数据相减或者相加时,得到天数,当运用这个值进行运算会报错:ufunc true_divide cannot use operands with types dtype('int64') and dtype('<m8[ns]'),我们只需要把'<m8[ns]'类型数据转换为int就可以继续运算 l = df1['计划结束时间'] - df1['计划开始时间']为: 这个数据是不能进行加减运算的 L = l.values / (24*60*60*100

data类型的url

??所谓"data"类型的Url格式,是在RFC2397中 提出的,目的对于一些"小"的数据,可以在网页中直接嵌入,而不是从外部文件载入.例如对于img这个Tag,哪怕这个图片非常非常的小,小到只有一个 点,也是要从另外一个外部的图片文件例如gif文件中读入的,如果浏览器实现了data类型的Url格式,这个文件就可以直接从页面文件内部读入了. 例:下面这一段代码放到url地址栏访问会得到一个加粗的"Hello, world!" data:text

pandas: powerful Python data analysis toolkit

pandas.read_csv pandas.read_csv(filepath_or_buffer, sep=', ', delimiter=None, header='infer', names=None, index_col=None, usecols=None, squeeze=False, prefix=None, mangle_dupe_cols=True, dtype=None, engine=None, converters=None, true_values=None, fal