代码之家  ›  专栏  ›  技术社区  ›  jwimberley

熊猫“支点”操作的精确逆运算

  •  4
  • jwimberley  · 技术社区  · 6 年前

    我有一个粗略格式的熊猫数据帧

    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 在每个现有的( , 群铅 )配对),我发现最容易计算这些值的方法是首先将数据透视到表单中:

    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_pivot ,并填充它,但我更喜欢使用内置函数。尽我所能尝试使用 df.melt ,我无法执行此反转,因为 DFI枢轴 的分层列。我最好的尝试是

    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 回复  |  直到 6 年前
        1
  •  4
  •   BENY    6 年前

    我想 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