【问题标题】:Convert an n x 1 dataframe to an a x b sized grid based on month, year根据月、年将 n x 1 数据帧转换为 a x b 大小的网格
【发布时间】:2020-05-13 13:42:50
【问题描述】:

我有一个带有日期时间索引的 pandas 数据框,我想将其重新定位为来自 pandas 时间序列数据框的网格。

我的数据框如下所示:

DATE        VAL         
2007-06     0.008530
2007-07    -0.067069
2007-08     0.026660
2007-09     0.016237
2007-10     0.025145
2007-11    -0.063666
2007-12    -0.002118
2008-01    -0.059951
2008-02    -0.033422
2008-03     0.008978
2008-04     0.039997
2008-05     0.043563
2008-06    -0.076166
...

我想用[year] 行和[month] 列重新定位,看起来像这样:

      Jan       Feb      Mar    ...  Jun      Jul      Aug      Sep      Oct      Nov      Dec  
2007   0         0        0     ... .008530  -.067069 .026660  .016237  .025145  -.06366  -.025145 
2008  -.05995  -.033422 .00897  ... -.076166   ...
...

reshape/stack/unstack 方法似乎可以做一个我想要的版本,但由于我有一个单一的日期索引,这些不适合我的数据框。

【问题讨论】:

  • 可能已经在这里回答了:stackoverflow.com/questions/25146121/…
  • @SathishSanjeevi,不完全...年份和月份值可通过应用于索引的 yearmonth 方法获得,但如果没有应用程序,这并没有真正帮助

标签: python python-3.x pandas numpy


【解决方案1】:

首先将DATE 转换为日期时间,并通过DataFrame.set_indexSeries.unstack 进行整形,几个月使用Series.dt.strftime。列名的最后更改顺序由DataFrame.reindex 并由DataFrame.rename_axis 删除索引 namd 列名:

df['DATE'] = pd.to_datetime(df['DATE'])
m = ['Jan', 'Feb', 'Mar', 'Apr','May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
df1 = (df.set_index([df['DATE'].dt.year, df['DATE'].dt.strftime('%b')])['VAL']
         .unstack(fill_value=0)
         .reindex(columns=m)
         .rename_axis(index=None, columns=None))
print (df1)
           Jan       Feb       Mar       Apr       May       Jun       Jul  \
2007  0.000000  0.000000  0.000000  0.000000  0.000000  0.008530 -0.067069   
2008 -0.059951 -0.033422  0.008978  0.039997  0.043563 -0.076166  0.000000   

          Aug       Sep       Oct       Nov       Dec  
2007  0.02666  0.016237  0.025145 -0.063666 -0.002118  
2008  0.00000  0.000000  0.000000  0.000000  0.000000  

另一种解决方案是使用DataFrame.pivot,并使用ordered categoricals 进行正确排序:

df['DATE'] = pd.to_datetime(df['DATE'])
m = ['Jan', 'Feb', 'Mar', 'Apr','May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
df1 = (df.assign(m = pd.Categorical(df['DATE'].dt.strftime('%b'), ordered=True, categories=m),
               y = df['DATE'].dt.year)
         .pivot('y','m','VAL')
         .fillna(0)
         .rename_axis(index=None, columns=None))

print (df1)
           Jan       Feb       Mar       Apr       May       Jun       Jul  \
2007  0.000000  0.000000  0.000000  0.000000  0.000000  0.008530 -0.067069   
2008 -0.059951 -0.033422  0.008978  0.039997  0.043563 -0.076166  0.000000   

          Aug       Sep       Oct       Nov       Dec  
2007  0.02666  0.016237  0.025145 -0.063666 -0.002118  
2008  0.00000  0.000000  0.000000  0.000000  0.000000  

rename 列的解决方案:

d = {1: 'Jan', 2: 'Feb', 3: 'Mar', 4: 'Apr', 5: 'May', 6: 'Jun',
     7: 'Jul', 8: 'Aug', 9: 'Sep', 10: 'Oct', 11: 'Nov', 12: 'Dec'}
df1 = (df.set_index([df.index.year, df.index.month]).VAL
         .unstack(fill_value=0)
         .rename(columns=d))

【讨论】:

  • 太棒了。重新索引(如在第一个示例中)正在丢掉一些东西,所以我放弃了它并添加了不同的命名方式。以下作品:df = df.set_index([df.index.year, df.index.month]).VAL.unstack(fill_value=0) df.rename( columns={1: 'Jan', 2: 'Feb', 3: 'Mar', 4: 'Apr', 5: 'May', 6: 'Jun', 7: 'Jul', 8: 'Aug', 9: 'Sep', 10: 'Oct', 11: 'Nov', 12: 'Dec'}, inplace=True )
  • @Chris - 哟,只删除 inplace=True
  • 需要那个部分...否则只需返回屏幕
  • @Chris - 我认为这是一行,如果第二行是必要的
  • @Chris - 添加新段落我的意思
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-08
  • 2021-07-25
相关资源
最近更新 更多