【问题标题】:Pandas Group then Shift Column and keep last rowPandas Group 然后移动列并保留最后一行
【发布时间】:2018-11-12 21:59:30
【问题描述】:

我想对列 idx 进行分组,然后移动列 val 并将最后一行保留为 idx

import pandas as pd

df = pd.DataFrame({'idx':['a','a','b','b'],
                   'val':['a1','a2','b1','b2']})

df

   idx  val
0   a   a1
1   a   a2
2   b   b1
3   b   b2

我试过df['val_shift'] = df.groupby('idx').val.shift(1)

   idx  val val_shift
0   a   a1  NaN
1   a   a2  a1
2   b   b1  NaN
3   b   b2  b1

但我想要。

   idx  val
0   a   NaN
1   a   a1
2   a   a2
3   b   NaN
4   b   b1
5   b   b2

有没有办法得到这个?

【问题讨论】:

    标签: pandas dataframe


    【解决方案1】:

    我相信您需要 concat 提取的最后一行 drop_duplicates 并首先更改索引值以正确排序,因为 shift 总是在此处删除最后一个值:

    df1 = df.drop_duplicates('idx', keep='last')
    df1.index +=  .5
    
    df = pd.concat([df, df1]).sort_index().reset_index(drop=True)
    

    替代解决方案:

    df = df.drop_duplicates('idx', keep='last').append(df).sort_index().reset_index(drop=True)
    
    df['val_shift']  = df.groupby('idx').val.shift(1)
    print (df)
      idx val val_shift
    0   a  a1       NaN
    1   a  a2        a1
    2   a  a2        a2
    3   b  b1       NaN
    4   b  b2        b1
    5   b  b2        b2
    

    如果想在shift 之后删除val,请使用带有语法糖的pop - 按系列分组df['idx']

    df['val_shift']  = df.pop('val').groupby(df['idx']).shift(1)
    print (df)
      idx val_shift
    0   a       NaN
    1   a        a1
    2   a        a2
    3   b       NaN
    4   b        b1
    5   b        b2
    

    【讨论】:

    • 感谢您的好回答,但我有一些问题。最后一种方法是否给出最快的结果?我无法使用%timeit 对其进行测试。
    • @yolox - 也测试过了,你说得对,测试功能很必要,给我一些时间。
    • 经过测试,第二种解决方案更快。
    • 非常感谢!
    【解决方案2】:

    在我看来,您只是在每个仅填充 'idx' 的组前面推了一个空数据框。

    pd.concat([
        d[['idx']].head(1).append(d)
        for _, d in df.groupby('idx')
    ], ignore_index=True)    
    
      idx  val
    0   a  NaN
    1   a   a1
    2   a   a2
    3   b  NaN
    4   b   b1
    5   b   b2
    

    另类

    df[['idx']].drop_duplicates('idx').append(df).sort_values('idx').reset_index(drop=True)
    

    【讨论】:

      【解决方案3】:

      concattail 一起使用

      newdf=pd.concat([df,df.groupby('idx').tail(1)])
      newdf=newdf.assign(val=newdf.groupby('idx').shift()).sort_index()
      newdf
      Out[885]: 
        idx  val
      0   a  NaN
      1   a   a1
      1   a   a2
      2   b  NaN
      3   b   b1
      3   b   b2
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-06-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-23
        相关资源
        最近更新 更多