【问题标题】:Shift groupby by an unknown number of line将 groupby 移动未知的行数
【发布时间】:2020-08-26 08:42:31
【问题描述】:

我有一个来自数据框的数据透视表,其结构如下:

raw = pd.DataFrame([[123456,datetime(2020,7,1), "XXX",'A',1 ],
                   [123456,datetime(2020,7,1), "XXX",'B',2 ],
                   [123456,datetime(2020,7,1), "XXX",'C',3 ],
                   [123456,datetime(2020,7,1), "YYY",'A',4 ],
                   [123456,datetime(2020,7,1), "YYY",'B',5 ],
                   [123456,datetime(2020,7,1), "YYY",'C',6 ],
                   [123456,datetime(2020,7,2), "XXX",'A',7 ],
                   [123456,datetime(2020,7,2), "XXX",'B',8 ],
                   [123456,datetime(2020,7,2), "XXX",'C',float('NaN'),
                   [123456,datetime(2020,7,2), "YYY",'A',9 ],
                   [123456,datetime(2020,7,2), "YYY",'B',10 ],
                   [123456,datetime(2020,7,2), "YYY",'C',11 ],
                   [789012,datetime(2020,7,1), "XXX",'A',12 ],
                   [789012,datetime(2020,7,1), "XXX",'B',13 ],
                   [789012,datetime(2020,7,1), "XXX",'C',14 ],
                   [789012,datetime(2020,7,2), "XXX",'A',15 ],
                   [789012,datetime(2020,7,2), "XXX",'B',16 ],
                   [789012,datetime(2020,7,2), "XXX",'C',17 ],
                           ] , columns=['GROUP_ID','DATE', 'REFERENCE', 'NAME', 'VALUE'])

pt = raw.pivot_table(index=['GROUP_ID', 'DATE', 'REFERENCE'], columns=['NAME'], values=['VALUE'])

                              VALUE
                    NAME      A    B    C
GROUP_ID      DATE  REFERENCE           
123456  2020-07-01  XXX       1.0  2.0  3.0
                    YYY       4.0  5.0  6.0
        2020-07-02  XXX       7.0  8.0  NaN
                    YYY       9.0 10.0 11.0
789012  2020-07-01  XXX      12.0 13.0 14.0
        2020-07-02  XXX      15.0 16.0 17.0

这个想法是创建一个列("VALUE_PREV", "C"),我可以在每个GROUP_ID 中包含上一个日期的值。 如果我这样做 pt[("VALUE_PREV","C")] = pt["VALUE"].groupby(level=0)["C"].shift() 我有:

                                VALUE          VALUE_PREV
                         NAME   A    B    C      C
GROUP_ID      DATE  REFERENCE               
123456  2020-07-01  XXX        1.0   2.0   3.0  NaN
                    YYY        4.0   5.0   6.0  3.0
        2020-07-02  XXX        7.0   8.0   NaN  6.0
                    YYY        9.0  10.0  11.0  NaN
789012  2020-07-01  XXX       12.0  13.0  14.0  NaN
        2020-07-02  XXX       15.0  16.0  17.0 14.0

所以在VALUE_PREVcolumn 的最后一行14.0 的位置很好,但3.06.0 应该在下面一行。解决方案可能是执行shift(2),但REFERENCE 的日期取决于GROUP_ID,然后14.0 将是下面的一行。 所以我不知道如何获得每个GROUP_IDREFERENCE 数量来动态调整shift()

【问题讨论】:

    标签: python python-3.x dataframe group-by pivot-table


    【解决方案1】:

    提前在raw DataFrame 中执行此操作可能更容易解决此问题。

    首先,我们需要根据您的条件精确地创建一天的偏移量,为此我们需要一个tseries

    from pandas.tseries.offsets import DateOffset
    offset = DateOffset(days=1)
    

    然后我们需要创建移位值。

    shifted = raw.reset_index().set_index("DATE").shift(1, freq=offset).reset_index().drop(columns="index")
    

    然后我们可以将两个数据集连接在一起。

    df = raw.merge(shifted, how="left", on=["GROUP_ID", "DATE", "REFERENCE", "NAME"], suffixes=["CURRENT", "PREV"])
    

    最后我们调用你之前的数据透视函数。

    df.pivot_table(index=["GROUP_ID", "DATE", "REFERENCE"], columns="NAME", values=["VALUECURRENT", "VALUEPREV"])
    
                                  VALUECURRENT             VALUEPREV            
    NAME                                     A     B     C         A     B     C
    GROUP_ID DATE       REFERENCE                                               
    123456   2020-07-01 XXX                1.0   2.0   3.0       NaN   NaN   NaN
                        YYY                4.0   5.0   6.0       NaN   NaN   NaN
             2020-07-02 XXX                7.0   8.0   NaN       1.0   2.0   3.0
                        YYY                9.0  10.0  11.0       4.0   5.0   6.0
    789012   2020-07-01 XXX               12.0  13.0  14.0       NaN   NaN   NaN
             2020-07-02 XXX               15.0  16.0  17.0      12.0  13.0  14.0
    

    【讨论】:

    • 谢谢它的工作,只是为了确定,我得到与raw.set_index("DATE").shift(1, freq=offset).reset_index() 相同的结果而不是raw.reset_index().set_index("DATE").shift(1, freq=offset).reset_index().drop(columns="index")shifted,我错过了什么并且它在某些时候有用吗?
    • 不,任何一种方式都可以,一种方式比另一种方式更冗长
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-30
    • 1970-01-01
    • 1970-01-01
    • 2022-11-23
    • 1970-01-01
    相关资源
    最近更新 更多