zoukankan      html  css  js  c++  java
  • 10.29

    pandas将“长格式”旋转为“宽格式”

    多个时间序列数据通常是以所谓的“长格式”(long)或“堆叠格式”(stacked)存储在数据库和CSV中的。我们先加载一些示例数据,做一些时间序列规整和数据清洗:

    In [139]: data = pd.read_csv('examples/macrodata.csv')
    
    In [140]: data.head()
    Out[140]: 
         year  quarter   realgdp  realcons  realinv  realgovt  realdpi    cpi  
    0  1959.0      1.0  2710.349    1707.4  286.898   470.045   1886.9  28.98   
    1  1959.0      2.0  2778.801    1733.7  310.859   481.301   1919.7  29.15   
    2  1959.0      3.0  2775.488    1751.8  289.226   491.260   1916.4  29.35   
    3  1959.0      4.0  2785.204    1753.7  299.356   484.052   1931.3  29.37   
    4  1960.0      1.0  2847.699    1770.5  331.722   462.199   1955.5  29.54   
          m1  tbilrate  unemp      pop  infl  realint  
    0  139.7      2.82    5.8  177.146  0.00     0.00
    1  141.7      3.08    5.1  177.830  2.34     0.74  
    2  140.5      3.82    5.3  178.657  2.74     1.09  
    3  140.0      4.33    5.6  179.386  0.27     4.06  
    4  139.6      3.50    5.2  180.007  2.31     1.19  
    
    In [141]: periods = pd.PeriodIndex(year=data.year, quarter=data.quarter,
       .....:                          name='date')
    
    In [142]: columns = pd.Index(['realgdp', 'infl', 'unemp'], name='item')
    
    In [143]: data = data.reindex(columns=columns)
    
    In [144]: data.index = periods.to_timestamp('D', 'end')
    
    In [145]: ldata = data.stack().reset_index().rename(columns={0: 'value'})

    这就是多个时间序列(或者其它带有两个或多个键的可观察数据,这里,我们的键是date和item)的长格式。表中的每行代表一次观察。

    关系型数据库(如MySQL)中的数据经常都是这样存储的,因为固定架构(即列名和数据类型)有一个好处:随着表中数据的添加,item列中的值的种类能够增加。在前面的例子中,date和item通常就是主键(用关系型数据库的说法),不仅提供了关系完整性,而且提供了更为简单的查询支持。有的情况下,使用这样的数据会很麻烦,你可能会更喜欢DataFrame,不同的item值分别形成一列,date列中的时间戳则用作索引。DataFrame的pivot方法完全可以实现这个转换:

    In [147]: pivoted = ldata.pivot('date', 'item', 'value')
    
    In [148]: pivoted
    Out[148]: 
    item        infl    realgdp  unemp
    date                              
    1959-03-31  0.00   2710.349    5.8
    1959-06-30  2.34   2778.801    5.1
    1959-09-30  2.74   2775.488    5.3
    1959-12-31  0.27   2785.204    5.6
    1960-03-31  2.31   2847.699    5.2
    1960-06-30  0.14   2834.390    5.2
    1960-09-30  2.70   2839.022    5.6
    1960-12-31  1.21   2802.616    6.3
    1961-03-31 -0.40   2819.264    6.8
    1961-06-30  1.47   2872.005    7.0
    ...          ...        ...    ...
    2007-06-30  2.75  13203.977    4.5
    2007-09-30  3.45  13321.109    4.7
    2007-12-31  6.38  13391.249    4.8
    2008-03-31  2.82  13366.865    4.9
    2008-06-30  8.53  13415.266    5.4
    2008-09-30 -3.16  13324.600    6.0
    2008-12-31 -8.79  13141.920    6.9
    2009-03-31  0.94  12925.410    8.1
    2009-06-30  3.37  12901.504    9.2
    2009-09-30  3.56  12990.341    9.6
    [203 rows x 3 columns]

    前两个传递的值分别用作行和列索引,最后一个可选值则是用于填充DataFrame的数据列。假设有两个需要同时重塑的数据列:

    In [149]: ldata['value2'] = np.random.randn(len(ldata))
    
    In [150]: ldata[:10]
    Out[150]: 
            date     item     value    value2
    0 1959-03-31  realgdp  2710.349  0.523772
    1 1959-03-31     infl     0.000  0.000940
    2 1959-03-31    unemp     5.800  1.343810
    3 1959-06-30  realgdp  2778.801 -0.713544
    4 1959-06-30     infl     2.340 -0.831154
    5 1959-06-30    unemp     5.100 -2.370232
    6 1959-09-30  realgdp  2775.488 -1.860761
    7 1959-09-30     infl     2.740 -0.860757
    8 1959-09-30    unemp     5.300  0.560145
    9 1959-12-31  realgdp  2785.204 -1.265934

    如果忽略最后一个参数,得到的DataFrame就会带有层次化的列:

    In [151]: pivoted = ldata.pivot('date', 'item')
    
    In [152]: pivoted[:5]
    Out[152]: 
               value                    value2                    
    item        infl   realgdp unemp      infl   realgdp     unemp
    date                                                          
    1959-03-31  0.00  2710.349   5.8  0.000940  0.523772  1.343810
    1959-06-30  2.34  2778.801   5.1 -0.831154 -0.713544 -2.370232
    1959-09-30  2.74  2775.488   5.3 -0.860757 -1.860761  0.560145
    1959-12-31  0.27  2785.204   5.6  0.119827 -1.265934 -1.063512
    1960-03-31  2.31  2847.699   5.2 -2.359419  0.332883 -0.199543
    
    In [153]: pivoted['value'][:5]
    Out[153]: 
    item        infl   realgdp  unemp
    date                             
    1959-03-31  0.00  2710.349    5.8
    1959-06-30  2.34  2778.801    5.1
    1959-09-30  2.74  2775.488    5.3
    1959-12-31  0.27  2785.204    5.6
    1960-03-31  2.31  2847.699    5.2

    注意,pivot其实就是用set_index创建层次化索引,再用unstack重塑:

    In [154]: unstacked = ldata.set_index(['date', 'item']).unstack('item')
    
    In [155]: unstacked[:7]
    Out[155]: 
               value                    value2                    
    item        infl   realgdp unemp      infl   realgdp     unemp
    date                                                          
    1959-03-31  0.00  2710.349   5.8  0.000940  0.523772  1.343810
    1959-06-30  2.34  2778.801   5.1 -0.831154 -0.713544 -2.370232
    1959-09-30  2.74  2775.488   5.3 -0.860757 -1.860761  0.560145
    1959-12-31  0.27  2785.204   5.6  0.119827 -1.265934 -1.063512
    1960-03-31  2.31  2847.699   5.2 -2.359419  0.332883 -0.199543
    1960-06-30  0.14  2834.390   5.2 -0.970736 -1.541996 -1.307030
    1960-09-30  2.70  2839.022   5.6  0.377984  0.286350 -0.753887
  • 相关阅读:
    086 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 03 面向对象基础总结 01 面向对象基础(类和对象)总结
    085 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 04 构造方法调用
    jQuery UI组件库Kendo UI使用技巧小分享
    Kendo UI ListView模板功能,让Web开发更轻松
    UI组件套包DevExpress ASP.NET Core v20.2新版亮点:全新的查询生成器
    Devexpress WinForms最新版开发.NET环境配置Visual Studo和SQL Server对应版本
    全新的桌面应用数据可视化呈现方式,Sankey Diagram控件你了解多少?
    java中的递归方法
    连接数据库查询 将查询结果写入exce文件中
    java连接mysql数据查询数据
  • 原文地址:https://www.cnblogs.com/zhaoyids/p/14867146.html
Copyright © 2011-2022 走看看