首页 > 解决方案 > 根据月、年将 nx 1 数据帧转换为 axb 大小的网格

问题描述

我有一个带有日期时间索引的 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 方法似乎可以执行我想要的版本,但是由于我有一个日期索引,因此这些方法不适合我的数据框。

标签: pythonpython-3.xpandasnumpy

解决方案


首先转换为日期时间并通过withDATE重塑,以供几个月使用。列名的最后更改顺序 by并删除索引 namd 列名 by :DataFrame.set_indexSeries.unstackSeries.dt.strftimeDataFrame.reindexDataFrame.rename_axis

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,并且为了正确排序,使用有序的分类s:

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))

推荐阅读