熊猫“枢轴”操作的确切逆过程

时间:2018-09-10 17:43:41

标签: python pandas pivot melt

我有一个粗略的熊猫数据框

print(df)
    Time  GroupA  GroupB  Value1  Value2
0  100.0     1.0     1.0    18.0     0.0
1  100.0     1.0     2.0    16.0     0.0
2  100.0     2.0     1.0    18.0     0.0
3  100.0     2.0     2.0    10.0     0.0

其中Time是计数变量/时间戳,GroupAGroupB是类别,Value1Value2是数值。此代码段创建了一个模型数据框:

import numpy as np
values = np.zeros(shape=(4,5))
values[:,0] = 100
values[:,1] = [1]*2 + [2]*2
values[:,2] = [1,2]*2
values[:,3] = np.random.randint(low=10,high=20,size=(4))
df = pd.DataFrame(values,columns=['Time','GroupA','GroupB','Value1','Value2'])

装入一些数据后,我要计算并填写Value2的值。碰巧(由于Value2是每个现有(Value1GroupA)对中GroupB的时间序列函数),我发现最简单的计算方法是首先将我的数据转换为以下形式的值:

df_pivot = df.pivot_table(index='Time',columns=['GroupA','GroupB'],values=['Value1','Value2'], fill_value=0.0)

然后在一些无关的代码之后,我填写了值

print(df_pivot)
       Value1             Value2            
GroupA    1.0     2.0        1.0     2.0    
GroupB    1.0 2.0 1.0 2.0    1.0 2.0 1.0 2.0
Time                                        
100.0      13  16  16  10     27  20  28  20

现在,我想将其“取消旋转”回原始格式df。我可以通过遍历df,在df_pivot中查找值并填充它来手动完成此操作,但是我更喜欢使用内置函数。尝试使用df.melt的变体,由于df_pivot的层次列存在问题,我无法执行此反转。我最好的尝试是

dfm = df_pivot.reset_index().melt(id_vars="Time")
dfm.columns.values[1] = "HACK"
dfm = dfm.pivot_table(index=["Time","GroupA","GroupB"],columns="HACK",values="value").reset_index()

产生数据帧

print(dfm)
HACK   Time  GroupA  GroupB  Value1  Value2
0     100.0     1.0     1.0      13      27
1     100.0     1.0     2.0      16      20
2     100.0     2.0     1.0      16      28
3     100.0     2.0     2.0      10      20

这可行,但不是最佳解决方案,也不是非常便于移植(为什么melt会产生“ NaN”列名称?为什么我需要手动找到该列的索引并重命名?为什么?我必须要枢轴才能撤消枢轴吗?)尽管尝试并浏览了文档和示例,但我还是一头雾水。 melt函数有一个col_level参数,看起来应该有所帮助,但是我为此使用的任何有效值只会导致数据丢失(丢失“ Time”,“ GroupA”或“ GroupB”数据)。

1 个答案:

答案 0 :(得分:4)

我认为stack更简单

df_pivot.stack([1,2]).reset_index()
Out[8]: 
    Time  GroupA  GroupB  Value1  Value2
0  100.0     1.0     1.0      13       0
1  100.0     1.0     2.0      13       0
2  100.0     2.0     1.0      12       0
3  100.0     2.0     2.0      11       0