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
  • 相关阅读:
    【java】对象赋值给另一个对象
    spring boot系列(五)spring boot 配置spring data jpa (查询方法)
    Spring Data JPA 查询
    Spring Data JPA 介绍
    OpenID简介
    OAUTH协议介绍
    URL encoding(URL编码)
    RESTful 介绍
    spring boot系列(四)spring boot 配置spring data jpa (保存修改删除方法)
    spring boot 启动报 java.lang.NoClassDefFoundError: ch/qos/logback/core/spi/LifeCycle 错误
  • 原文地址:https://www.cnblogs.com/zhaoyids/p/14867146.html
Copyright © 2011-2022 走看看