pandas' "pivot" 操作的精确逆运算
Exact inverse of pandas' "pivot" operation
我有一个 pandas 粗略格式的数据框
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
是每个现有 (GroupA
、GroupB
) 对中 Value1
的时间序列函数),我发现最容易计算这些首先将我的数据转换为以下形式的值:
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
现在我想"unpivot"把它恢复成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" 数据)。
我觉得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
我有一个 pandas 粗略格式的数据框
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
是每个现有 (GroupA
、GroupB
) 对中 Value1
的时间序列函数),我发现最容易计算这些首先将我的数据转换为以下形式的值:
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
现在我想"unpivot"把它恢复成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" 数据)。
我觉得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