2014-10-09 15 views
11

Mam ramkę danych Pandy i chcę utworzyć nową kolumnę, której wartości odpowiadają innej kolumnie, przesuniętej w dół o jeden wiersz. Ostatni wiersz powinien pokazywać NaN.Pandy: Przesunięcie wartości o jeden wiersz w grupie

Połów jest taki, że chcę to zrobić w grupie, przy czym ostatni wiersz każdej grupy pokazuje NaN. NIE ma ostatniego wiersza grupy, która "kradnie" wartość z grupy, która przylega do ramki danych.

Moja próba wdrożenia została dość haniebnie zerwana, więc wyraźnie nie rozumiem czegoś fundamentalnego.

df['B_shifted'] = df.groupby(['A'])['B'].transform(lambda x:x.values[1:]) 
+3

Czy to działa: 'df ['B_shifted'] = df.groupby (['A']) ['B']. Transform (lambda x: x.shift())'? – EdChum

+3

Ilekroć w Pandzie jest coś nieco podstępnego, chcę napisać funkcję, która właśnie to robi. Tylko że nigdy nie wiem, że istnieje i jak go znaleźć! – jeffalstott

Odpowiedz

6

Przesunięcie działa na mocy klauzuli GroupBy:

>>> df = pandas.DataFrame(numpy.random.randint(1,3, (10,5)), columns=['a','b','c','d','e']) 
>>> df 
    a b c d e 
0 2 1 2 1 1 
1 2 1 1 1 1 
2 1 2 2 1 2 
3 1 2 1 1 2 
4 2 2 1 1 2 
5 2 2 2 2 1 
6 2 2 1 1 1 
7 2 2 2 1 1 
8 2 2 2 2 1 
9 2 2 2 2 1 


for k, v in df.groupby('a'): 
    print k 
    print 'normal' 
    print v 
    print 'shifted' 
    print v.shift(1) 

1 
normal 
    a b c d e 
2 1 2 2 1 2 
3 1 2 1 1 2 
shifted 
    a b c d e 
2 NaN NaN NaN NaN NaN 
3 1 2 2 1 2 
2 
normal 
    a b c d e 
0 2 1 2 1 1 
1 2 1 1 1 1 
4 2 2 1 1 2 
5 2 2 2 2 1 
6 2 2 1 1 1 
7 2 2 2 1 1 
8 2 2 2 2 1 
9 2 2 2 2 1 
shifted 
    a b c d e 
0 NaN NaN NaN NaN NaN 
1 2 1 2 1 1 
4 2 1 1 1 1 
5 2 2 1 1 2 
6 2 2 2 2 1 
7 2 2 1 1 1 
8 2 2 2 1 1 
9 2 2 2 2 1 
+0

domyślny parametr przesunięcia to 1, więc nie trzeba ustawiać 'shift (1)' chociaż jest to wyraźniejszy kod, określając go – EdChum

9

@ komentarz EdChum jest lepsza odpowiedź na to pytanie, więc jestem delegowania go tutaj dla potomności:

df['B_shifted'] = df.groupby(['A'])['B'].transform(lambda x:x.shift())

lub podobnie

df['B_shifted'] = df.groupby(['A'])['B'].transform('shift').

Dawna notacja jest bardziej elastyczna, oczywiście (np. Jeśli chcesz przesunąć o 2).

15

Nowsze wersje pandy może teraz wykonać shift na grupy:

df['B_shifted'] = df.groupby(['A'])['B'].shift(1) 

Należy pamiętać, że podczas przechodzenia dół, że to pierwszy rząd, który ma Nan.

Powiązane problemy