Pandas Group, затем Shift Column и оставьте последний ряд - PullRequest
0 голосов
/ 12 ноября 2018

Я хочу сгруппировать столбец 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

Есть ли способ получить это?

Ответы [ 3 ]

0 голосов
/ 12 ноября 2018

Мне кажется, что вы просто добавляете пустой информационный фрейм в каждую группу, где заполнено только '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)
0 голосов
/ 12 ноября 2018

Использование concat с tail

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
0 голосов
/ 12 ноября 2018

Я полагаю, вам нужно 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

Если хотите удалить val после shift, используйте 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...