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