zoukankan      html  css  js  c++  java
  • Pandas数据规整

    Pandas数据排序

    .sort_index() 在指定轴上根据索引进行排序,索引排序后内容会跟随排序

    b = pd.DataFrame(np.arange(20).reshape(4,5),index=['c','a','d','b'])
    b.sort_index()  # 默认按行索引排序,默认升序
    b.sort_index(ascending=False)
    b.sort_index(axis=1,ascending=False)  # 按列索引排序,降序
    

    sort_values() 按值排序

    dates = pd.date_range('20130101', periods = 10)
    df = pd.DataFrame(np.random.randn(10,4), index = dates, columns = ['A','B','C','D'])
    df.sort_values(by='A')  # 指定排序基准列
    df.sort_values(by='A', ascending=False)  # 倒序
    # 按列排序(一行的所有列)
    df.sort_values(axis=1, by='2013-01-01', ascending=False)
    

    关于排序中的缺失值问题

    排序不论升序降序,缺失值永远排在最后

    a = pd.DataFrame(np.arange(12).reshape(3,4), index=['a','b','c'])
    a
    b = pd.DataFrame(np.arange(20).reshape(4,5), index=['c','a','d','b'])
    b
    c = a + b
    c.sort_values(by=0) # 升序,缺失值在最后
    c.sort_values(by=0, ascending=False)# 降序,缺失值还在最后
    

    随机排列和随机采样

    随机排列

    利用numpy.random.permutation函数可以实现对Series或DataFrame的列的随机排序工作(permuting,随机重排序)

    通过需要排列的轴的长度调用permutation,可产生一个表示新顺序的整数数组:

    # 随机排列序列
    a = [1,2,3,4,5,6,7]
    np.random.permutation(a)
    df = pd.DataFrame(np.arange(5 * 4).reshape((5, 4)))
    df.index
    df.columns.values
    # 打乱行索引
    np.random.permutation(df.index)
    df.loc[np.random.permutation(df.index)]
    # 随机重排行索引和列索引
    index = np.random.permutation(df.index)
    index
    columns = np.random.permutation(df.columns.values)
    columns
    df.loc[index,columns]
    

    随机采样

    choice(),从一个序列中随机抽取某些值

    a = [1,2,3,4,5,6,7]
    np.random.choice(a)
    np.random.choice(a,size=3,replace=False)  # 保证这三次取出的没用重复值
    # 按行索引采样
    df.loc[np.random.choice(df.index,size=2,replace=False)]
    
    # 按行、按列随机采样
    index = np.random.choice(df.index,size=3,replace=False)
    columns = np.random.choice(df.columns.values,size=2,replace=False)
    df.loc[index,columns]
    

    重新索引(修改索引)

    reindex() ,重新索引,创建一个适应新索引的新对象

    一种变相的查询方式,类似在查询中加入新行新列

    • 直接赋值修改索引
    • set_index(), reset_index():普通行列和索引互相转换
    • rename是将原索引某些值替换为新值
    • reindex则是将整个索引重建(并不替换索引值,而是增减索引或改变顺序,原索引对应的值关系不变)
      • reindex可以理解为一种查询方式
        • loc查询如果索引值不存在,会报警告
        • reindex查询如何索引值不存在,会新增一行或一列新值,值为缺失值

     

    1.set_index
    DataFrame可以通过set_index方法,可以设置单索引和复合索引。
    DataFrame.set_index(keys, drop=True, append=False, inplace=False, verify_integrity=False)
    append添加新索引,drop为False,inplace为True时,索引将会还原为列。
    b = pd.DataFrame(np.arange(20).reshape(4,5),index=['c','a','d','b'])
    b.set_index(4) #指定列索引
    b.set_index([4,3]) 
    2.reset_index
    reset_index可以还原索引,重新变为默认的整型索引
    DataFrame.reset_index(level=None, drop=False, inplace=False, col_level=0, col_fill=”)
    level控制了具体要还原的那个等级的索引
    drop为False则索引列会被还原为普通列,否则会丢失
    bb = b.set_index([4,3])
    bb.reset_index()
    

    直接修改索引

    有问题,不合适

    • 索引修改后,值没有跟着变化
    • 修改值必须和原索引长度保持一致,不能增加或删除索引
    obj = pd.Series([4.5,7,2,-5.3], index=['d','b','a','c'])
    obj.index  #obj.index.values
    obj.index=['a','b','c','d']
    # obj.index = ['a','b','c']  # 长度不一致,报错
    

    使用rename修改索引

    只能替换已有索引

    obj.rename({'a': 'aaa', 'b': 'bbb', 'x': 'xx'})
    

      

    正规做法:使用reindex()重新索引

    obj.reindex(['b', 'd', 'a'])  # 删除值
    obj.reindex(['a','b','c','d','e'])  # 增加值
    obj.reindex(['a','b','c','d','e'],fill_value=0)
    # example
    obj2 = pd.Series(['blue','purple','yellow'], index = [0,2,4])
    obj2
    obj2.reindex(range(6),fill_value=0)
    # 前向,后向填充
    obj2.reindex(range(6), method='ffill')
    obj2.reindex(range(6), method='bfill')
    

    DataFrame索引重建

    # 重建行索引
    frame.reindex(['数学', '英语', '语文'])
    frame.reindex(['数学', '编程', '语文'])
    frame.reindex(index=['数学', 'english', '语文'])
    # 重建行列索引
    frame.reindex(['张三', '赵六', '王五'], axis=1)
    frame.reindex(columns=['张三', '赵六', '王五'])
    # 行&列
    frame.reindex(index=['语文', '编程', '英语'], columns=['张三', '赵六', '王五'])
    
    # 索引可以直接赋值修改,但是不能直接修改单个索引
    frame.index = [1,2,3]
    frame.columns = [1,2,3]
    frame.reindex(index=[1,2,10,4], columns=[3,1,5,2])   
    

    带有重复值的轴索引

    许多Pandas函数要求标签唯一,但这不是强制的

    obj = pd.Series(range(5), index=['a','a','b','b','c'])
    obj
    obj.index.is_unique
    

      

      

    Pandas数据规整 - 转换 - 层次化索引


    层次化索引(hierarchical indexing)使你能在一个轴上拥有超过1个索引级别,

    多层索引可以对数据结构升维,能以低维度形式处理高维度数据

    用多层索引 (Multi-index) 的 Series/DataFrame,存储2维/3维或以上维度的信息

    Pandas的三维以上数据处理:
    一起使用三维以上数据类型:面板数据(panel)处理,这个数据类型已被废弃
    维度不高的可用层次化索引,
    维度高的可以使用pydata出品的专用库 xarray 处理(其数据类型可以和Pandas互相转换)

    Series层次化索引的查询

    data = pd.Series(np.random.randn(9), index=[['a', 'a', 'a', 'b', 'b', 'c', 'c', 'd', 'd'], [1, 2, 3, 1, 3, 1, 2, 2, 3]])
    data
    
    # 默认索引
    data[0]  # 查询单值
    data[[0, 3]]  # 查询多值
    data[1:4]  # 切片
    
    # 自定义索引,默认查询外层索引
    data['a']  # 查询单值
    data[['a', 'c']]  # 查询多值
    data['a':'c']  # 切片
    

      

    将层次化索引的Series转为DataFrame

    多层索引的 Series 其实和 DataFrame 维度一样,只是展示形式不同

    重塑就是通过改变数据表里面的 行索引 和 列索引 来改变展示形式

    data.unstack()
    # 自定义索引,默认查询外层索引
    data.unstack()[1]  # 查询列
    data.unstack().loc['a']  # 查询行
    data.unstack().loc['a', 2]  # 行,列
    
    # DataFrame交换
    data.unstack()
    data.unstack().T
    
    
    # Series交换
    data.unstack().T.stack()
    data.unstack().unstack().dropna()
    

      

    DataFrame层次化索引

    二维DataFrame转为多维

    使用DataFrame的列或行进行索引(重要)

    使用set_index()将DataFrame的一个或多个列当做行索引来用,或者将行索引变成DataFrame的列

    frame2 = pd.DataFrame(
        {'a': range(7), 'b': range(7, 0, -1),
         'c': ['one', 'one', 'one', 'two', 'two', 'two', 'two'],
         'd': [0, 1, 2, 0, 1, 2, 3]}
    )
    
    frame2.set_index('a')
    frame3 = frame2.set_index(['c', 'd'])
    
    frame2.set_index(['c', 'd'], append=True)  # 增加索引,非替换,保留原索引
    frame2.set_index(['c', 'd'], drop=False)  # 列转索引后,保留原列
    
    #行索引转为普通列
    frame3.reset_index()
    
    #frame2转换列索引
    # 先将原表转置,修改行索引后,再转置
    frame2.T.set_index(0, append=True).T
    

    通过修改行列索引值实现层次化索引

    symbol = ['BABA', 'JD', 'AAPL', 'MS', 'GS', 'WMT']
    data = {'行业': ['电商', '电商', '科技', '金融', '金融', '零售'],
            '价格': [176.92, 25.95, 172.97, 41.79, 196.00, 99.55],
            '交易量': [16175610, 27113291, 18913154, 10132145, 2626634, 8086946],
            '雇员': [101550, 175336, 100000, 60348, 36600, 2200000]}
    df2 = pd.DataFrame(data, index=symbol)
    
    df2.name='美股'
    df2.index.name = '代号'
    
    # 正确:使用MultiIndex赋值
    df2.index = pd.MultiIndex.from_tuples(
        [('中国公司','BABA'), ('中国公司','JD'), ('美国公司','AAPL'), ('美国公司','MS'), ('美国公司','GS'), ('美国公司','WMT')],
        names=('country', 'company'),
    )
    
    # 没有列索引层次化方法,可以转置后操作原列索引
    df2x = df2.T
    
    df2x.index = pd.MultiIndex.from_tuples([('aaa', '行业'),('aaa','价格'),('bbb','交易量'),('bbb','雇员')], names=('ab', '情况'))
    df2x.T
    

      

    直接创建多层索引DataFrame

    frame = pd.DataFrame(
        np.arange(12).reshape((4, 3)),
        index=[['a', 'a', 'b', 'b'], [1, 2, 1, 2]],
        columns=[['Ohio', 'Ohio', 'Colorado'],['Green', 'Red', 'Green']],
    )
    
    frame.index.names = ['key1', 'key2']
    frame.columns.names = ['state', 'color']
    
    # 或者这样创建
    midx = pd.MultiIndex(
        levels=[['a', 'b'], [1, 2]],
        codes=[[0, 0, 1, 1], [0, 1, 0, 1]],
        names=['key1', 'key2']
    )
    mcol = pd.MultiIndex(
        levels=[[ 'Colorado', 'Ohio'], ['Green', 'Red']],
        codes=[[1, 1, 0],[0, 1, 0]],
        names=['state', 'color']
    )
    
    frame = pd.DataFrame(
        np.arange(12).reshape((4, 3)),
        index=midx,
        columns=mcol,
    )
    

    DataFrame层次化索引查询

    # 简陋查询,-->列
    frame['Ohio']
    frame['Ohio','Red']  # 外列-内列'
    
    # loc
    frame.loc['a']  # 外行  返回dataframe
    frame.loc['a','Ohio']   # 外行-外列    返回dataframe
    frame.loc['a',2]        #外行-内行  返回Series
    # 外层行,内层行,外层列,内层列   ,2维series可以unstack为dataframe
    frame.loc['a', 1]['Ohio', 'Red']
    # 外层行,外层列,内层行,内层列
    frame.loc['a', 'Ohio'].loc[1, 'Red']
    

    重排与分级排序

    调整某条轴上各级别的顺序,或根据指定级别上的值对数据进行排序

    frame.swaplevel()  # 默认交换行索引
    
    frame.swaplevel('key2', 'key1')  # 手动指定调换索引name
    frame.swaplevel('key1', 'key2')  # 交换顺序,效果一样
    
    frame.swaplevel(0, 1)  # 手动指定调换索引层级
    frame.swaplevel(1, 0)
    frame.swaplevel(axis=1)  # 交换列索引
    frame.sort_index(ascending=False)  # 行索引排序(优先最外层索引)
    frame.sort_index(ascending=False, level='key2')  # 排序索引层级
    
    frame.sort_index(ascending=False, axis=1)  # 列索引排序

    根据级别汇总统计

    许多对DataFrame和Series的描述和汇总统计函数都有一个level选项,它用于指定在某条轴上计算的级别

    其实是利用了pandas的groupby功能

    frame.sum()  # 按行求和
    frame.sum(level='key1')  # 以key1索引分组求和
    # 用groupby实现
    
    # 以外层行索引为分组基准a
    frame.groupby('key1').sum()  # 分组基准,行索引name
    frame.groupby(level='key1').sum()  # level传入分组基准
    frame.groupby(['a', 'a', 'b', 'b']).sum()  # 手动构造分组基准
    
    # 以内层行索引为分组基准
    frame.groupby('key2').sum()  # 分组基准,行索引name
    frame.groupby(level='key2').sum()  # level传入分组基准
    frame.groupby([1,2,1,2]).sum()  # 手动构造分组基准
    
    frame.sum(axis=1)   # 按列求和
    #以内层列索引为基准实现
    frame.sum(axis=1, level='color')  # 两个 Green 相加
    # 用分组实现
    frame.groupby(['Green', 'Red', 'Green'], axis=1).sum()
    frame.groupby(axis=1, level='color').sum()
    
    
    #以外层列索引为基准
    frame.sum(axis=1, level='state')  # Ohio下的两列相加
    frame.groupby(level='state', axis=1).sum().sort_index(ascending=False, axis=1)
    # 和上面的区别:使用手打的分组基准代替level定义
    # 报错,直接传入分组索引值,默认使用最里层列索引
    # frame.groupby(['Ohio', 'Ohio', 'Colorado'], axis=1).sum().sort_index(ascending=False, axis=1)
    
    # 列索引交换层级
    frame.swaplevel(axis=1)
    frame.swaplevel(axis=1).groupby(['Ohio', 'Ohio', 'Colorado'], axis=1).sum().sort_index(ascending=False, axis=1)
    本文为原创文章,转载请标明出处
  • 相关阅读:
    A/B-test
    LDA概率主题模型
    减肥经验帖
    wide and deep
    利用责任链模式设计一个拦截器
    分享几个 SpringBoot 实用的小技巧
    「造个轮子」——cicada 设计一个配置模块
    「造个轮子」——cicada 源码分析
    「造个轮子」——cicada(轻量级 WEB 框架)
    强如 Disruptor 也发生内存溢出?
  • 原文地址:https://www.cnblogs.com/harden13/p/13490725.html
Copyright © 2011-2022 走看看