• pandas 数据类型研究(三)数据类型object与category


    数据类型object与category比较

    category数据类型

    官方文档是这样描述的:

    Categoricals 是 pandas 的一种数据类型,对应着被统计的变量。

      1.Categoricals 是由固定的且有限数量的变量组成的。比如:性别、社会阶层、血型、国籍、观察时段、赞美程度等等。

      2.与其它被统计的变量相比,categorical 类型的数据可以具有特定的顺序——比如:按程度来设定,“强烈同意”与“同意”,“首次观察”与“二次观察”,但是不能做按数值来进行排序操作

                                              (比如:sort_by 之类的,换句话说,categorical 的顺序是创建时手工设定的,是静态的)

      3.类型数据的每一个元素的值要么是预设好的类型中的某一个,要么是空值(np.nan)。

      4.categorical 实例的内部是由类型名字集合和一个整数组成的数组构成的,后者标明了类型集合真正的值。顺序是由预设好的类型集合来决定的,而不是按照类型集合中各个元素的字母顺序排序的。

    创建 Categorical 数据

    转化创建[object=>category]

    用一段代码从不同角度来展现一下 categorical 类型的数据。

    # 用一组数据记录各自的得分情况
    import pandas as pd, numpy as np
    players=['Garsol','Hardon','Bill']
    scores=[22,34,12,]
    teams=['West','West','East']
    df=pd.DataFrame({'player':players,'score':scores,'team':teams})
    print("df.player.dtype:",df.player.dtype)
    df

     把team字段转为category数据类型

    df["team"].astype('category')

    df.team 的变量类型变成了 category
     相似用法factorize
    colors = pd.DataFrame(['Garsol','Hardon','Bill'],columns=['name'])
    pd.factorize(colors['name'])

    这个返回值是个tuple,内有两个元素。

    动态添加category数据类型

    如按照得分来划分,将高于平均分的划为 Star,低于平均分的划为 Role。计算过程就应该是这样:
    d=pd.Series(scores).describe()
    score_ranges=[d['min']-1,d['mean'],d['max']+1]
    score_labels=['Role','Star']
    # 用pd.cut(ori_data, bins, labels) 方法
    # 以 bins 设定的画界点来将 ori_data 归类,然后用 labels 中对应的 label 来作为分类名
    df['level']=pd.cut(df['score'],score_ranges,labels=score_labels)
    df

    df['team']

    df['level']

    直接创建 category类型数据

    roles=pd.Categorical(['Role','xxx','Star'],categories=['Role', 'Star'])
    roles

     构造方法中第二个参数是指定了实例中可以包含的元素,在第一个参数中的元素如果不在 categories 中,就会被转成NaN。

    df=pd.DataFrame({'players':['Garsol','Hardon','Bill']})
    df['level']=roles
    df['level']

    内存占用分析

    import pandas as pd
    colors = pd.Series(['periwinkle','mint green','burnt orange','periwinkle','burnt orange','rose','rose','mint green','rose','navy'])
    print('colors type:',colors.dtype,'===>','memory_usage():',colors.memory_usage(index=False, deep=True))
    colors=colors.astype('category')
    print('colors type:',colors.dtype,'===>','memory_usage():',colors.memory_usage(index=False, deep=True))
    colors=colors.astype('category').cat.codes
    print('colors type:',colors.dtype,'===>','memory_usage():',colors.memory_usage(index=False, deep=True))

    import matplotlib.pyplot as plt
    plt.rcParams['font.sans-serif']=['Microsoft YaHei']
    colors = pd.Series(['periwinkle','mint green','burnt orange','periwinkle','burnt orange','rose','rose','mint green','rose','navy'])
    x=range(20)
    y1=[]
    y2=[]
    y3=[]
    for i in x:
        colorss=colors.repeat(i)
        y1.append(colorss.memory_usage(index=False, deep=True))
        colorss=colorss.astype('category')
        y2.append(colorss.memory_usage(index=False, deep=True))
        colorss=colorss.cat.codes
        y3.append(colorss.memory_usage(index=False, deep=True))
    
    plt.plot(x,y1,label='object')
    plt.plot(x,y2,label='category')
    plt.plot(x,y3,label='int')
    
    # x轴标签
    plt.xlabel('数据量')
    # y轴标签
    plt.ylabel('内存占用')
    
    # 可视化图标题
    plt.title('object-category-int数据类型研究')
    
    # 显示图例
    plt.legend()
    # 显示图形
    plt.show() 
    print('y1',y1)
    print('y2',y2)
    print('y3',y3)
    object-category-int数据类型研究

     内存占用区别:

    1.object所占用的内存则是一个常数乘以数据的长度。这个斜率为很大。

    2.int类型基本一个常数乘以数据的长度。这个初始值为0且为10(这里int16)

    3.初始值80增速也很慢最终增速为同(2)

    其实我们能猜测到category存储的方式,数据用int存储然后再维持一个从int到category的映射。

    所以Category内存是成比例的,如果数据集的数据量很大,但不重复分类(unique)值很少的情况下,那么Category的内存占用可以大大的节约内存。

    计算效率分析

    除了占用内存节省外,另一个额外的好处是计算效率有了很大的提升。

    因为对于Category类型的Series,str字符的操作发生在.cat.categories的非重复值上,而并非原Series上的所有元素上。

    也就是说对于每个非重复值都只做一次操作,然后再向与非重复值同类的值映射过去。

    对于Category的数据类型,可以使用accessor的cat对象,以及相应的属性和方法来操作Category数据。

    colors = pd.Series(['periwinkle','mint green','burnt orange','periwinkle','burnt orange','rose','rose','mint green','rose','navy'])
    colorss=colors.repeat(10001)
    colorss.astype('category').cat.categories

     实际上,对于开始的整数类型映射,我们可以先通过reorder_categories进行重新排序,然后再使用cat.codes来实现对整数的映射,来达到同样的效果。

    mapper={'Garsol':0,'Hardon':1,'Bill':2}
    names= pd.DataFrame(['Garsol','Hardon','Bill'],columns=['name'])
    colors

    names['alias']=names.name.astype('category').cat.codes
    names

    names['alias']=names.astype('category').name.cat.reorder_categories(mapper).cat.codes
    names

     names.astype('category').name.cat返回的是 pandas.core.arrays.categorical.CategoricalAccessor数据类型

     [i for i in dir(colors.astype('category').name.cat) if not i.startswith('_')]
    输出如下:
    ['add_categories',
     'as_ordered',
     'as_unordered',
     'categorical',
     'categories',
     'codes',
     'index',
     'name',
     'ordered',
     'remove_categories',
     'remove_unused_categories',
     'rename_categories',
     'reorder_categories',
     'set_categories']

     完结!!!

  • 相关阅读:
    windows 开发 数据模版 Itemtemp
    windows 8 获取用户账号信息
    从客户端中检测到有潜在危险的 Request.Form 值解决方法
    asp.net异步处理
    知道web.config 中的 urlMappings怎么用?
    .net c#日期时间函数大全
    设计模式学习心得之工厂类模式(一)简单工厂模式
    远程网页内容抓取
    TreeView数据绑定的方法(1)
    URLRewriter.dll asp.net伪静态
  • 原文地址:https://www.cnblogs.com/wqbin/p/12786217.html
Copyright © 2020-2023  润新知