如何使用 Pandas 将面板数据转置为正确的形式

How to transpose panel data into correct form using Pandas

我似乎在概念上为此苦苦挣扎,所以想不出我将如何编码。

我的数据框目前看起来像这样,我将 GMT 列拆分为日、月和年列,ID# 是每个家庭的 ID 号,下面的值是每次的 KwH 使用情况:

0    GMT         ID1    ID2   ID3   ...   ID1000   Day   Month   Year
1    01/01/2012  0.2    0.15  0.1   ...   0.1      1     1       2012
2    02/01/2012  0.3    0.2   0.2   ...   0.4      2     1       2012
3    03/01/2012  0.1    0.4   0.1   ...   0.5      3     1       2012
.    .           .      .     .     ...   .        .     .       . 
.    .           .      .     .     ...   .        .     .       . 
.    .           .      .     .     ...   .        .     .       .
1000 31/12/2012  0.3    0.2   0.05  ...   0.4      31    12      2012

但是我想将其转换为代表面板数据集的方式,使其看起来像:

0     ID   GMT         Day   Month   Year    KwH
1     1    01/01/2012  1     1       2012    0.2
2     1    02/01/2012  2     1       2012    0.3
3     1    03/01/2012  3     1       2012    0.1
.     .     .          .     .       .       .        
.     .     .          .     .       .       .        
.     .     .          .     .       .       .       
10000 1000 31/12/2012  31    12      2012    0.3

所以基本上我想以一种转置 ID 列的方式转置数据框,使它们成为行,并且与每个 ID 关联的数据按 GMT 分组,确保数据仍然与日期列正确匹配。

到目前为止,我一直在苦苦挣扎,因为 df.transpose() 函数似乎过于生硬,无法呈现我正在寻找的细微差别。

如有任何帮助,我们将不胜感激!

我使用了一个以 GMT 为索引的示例数据框。此外,您还可以获取晚些时候的日月年

            ID1  ID2    ID3  ID1000
GMT             
01/01/2012  0.2  0.15   0.1   0.1
02/01/2012  0.3  0.20   0.2   0.4
03/01/2012  0.1  0.40   0.1   0.5

然后您可以使用 unstackGMTID 组合为索引,将 KwH 组合为值

output_df = df.unstack().to_frame()
output_df

最后,您可以进行必要的更改以获得正确格式的 df

output_df = output_df.reset_index().rename(columns={'level_0': 'ID', 0: 'KwH'})
output_df['ID'] = output_df['ID'].str.replace('ID', '') # remove ID from the ID column values
output_df['GMT'] = pd.to_datetime(output_df['GMT'])
output_df['Day'] = output_df['GMT'].dt.day
output_df['Month'] = output_df['GMT'].dt.month
output_df['Year'] = output_df['GMT'].dt.year
output_df

这是针对您的一部分数据;您应该能够针对其余数据调整它:

    df = pd.DataFrame({'0': [1, 2, 3],
 'GMT': ['01/01/2012', '02/01/2012', '03/01/2012'],
 'ID1': [0.2, 0.3, 0.1],
 'ID2': [0.15, 0.2, 0.4],
 'ID3': [0.1, 0.2, 0.1],
 'ID1000': [0.1, 0.4, 0.5],
 'Day': [1, 2, 3],
 'Month': [1, 1, 1],
 'Year': [2012, 2012, 2012]})

rename 列,将 ID 列更改为 KwH:

 reshape = df.rename(
    columns=lambda col: col.replace("ID", "KwH") if "ID" in col else col
)
reshape.columns
Index(['0', 'GMT', 'KwH1', 'KwH2', 'KwH3', 'KwH1000', 'Day', 'Month',
       'Year'],
      dtype='object')

接下来应用pd.wide_to_long提取数据:

pd.wide_to_long(reshape, stubnames="KwH", i=["0", "GMT"], j="IDs", sep="")

                    Year    Month   Day KwH
0   GMT        IDs              
1   01/01/2012  1   2012    1   1   0.20
                2   2012    1   1   0.15
                3   2012    1   1   0.10
               1000 2012    1   1   0.10
2   02/01/2012  1   2012    1   2   0.30
                2   2012    1   2   0.20
                3   2012    1   2   0.20
              1000  2012    1   2   0.40
3   03/01/2012  1   2012    1   3   0.10
                2   2012    1   3   0.40
                3   2012    1   3   0.10
              1000  2012    1   3   0.50