我有粗略格式的熊猫数据帧
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
是计数变量/时间戳,GroupA
和GroupB
是类别,Value1
和Value2
是数字量。此代码段创建了一个模型数据框:
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
是Value1
在每个现有(GroupA
,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
这有效,但不会让我觉得是最好的解决方案,或者非常便携(为什么熔化产生“NaN”列名?为什么我手动找到这个列的索引并重命名呢?为什么我要这样做?枢轴撤消枢轴?)尝试并查看文档和示例以寻找替代方案,但我很茫然。 melt
函数有一个看起来应该有帮助的col_level
参数,但是我使用的任何有效值都会导致数据丢失(丢失“Time”,“GroupA”或“GroupB”数据)。
我认为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