Jak przesunąć kolumnę w Pandas DataFrame

101

Chciałbym przesunąć kolumnę w Pandach DataFrame, ale nie udało mi się znaleźć metody na zrobienie tego z dokumentacji bez przepisywania całego DF. Czy ktoś wie, jak to zrobić? Ramka danych:

##    x1   x2
##0  206  214
##1  226  234
##2  245  253
##3  265  272
##4  283  291

Pożądane wyjście:

##    x1   x2
##0  206  nan
##1  226  214
##2  245  234
##3  265  253
##4  283  272
##5  nan  291
korzeń
źródło
3
to naprawdę powinna być opcjonalna flaga dla funkcji shift
KIC

Odpowiedzi:

155
In [18]: a
Out[18]: 
   x1  x2
0   0   5
1   1   6
2   2   7
3   3   8
4   4   9

In [19]: a.x2 = a.x2.shift(1)

In [20]: a
Out[20]: 
   x1  x2
0   0 NaN
1   1   5
2   2   6
3   3   7
4   4   8
eumiro
źródło
9
Brak wyniku ## 5. Czy w pandach jest łatwy sposób na wydłużenie indeksu podczas korzystania z shift?
Waylon Walker
@WaylonWalker To się nazywa roll in numpy:df['x2'] = np.roll(df['x2'], 1)
ayhan
1
Czy ktoś to wymyślił? # 5 wciąż brakuje
Kritz
Muszę przesunąć 100 kolumn w ten sam sposób, jak mogę zrobić pętlę for?
Vincent Roye
2
@Johan, czy próbowałeś dodać pusty wiersz na końcu, zanim go przesunąłeś?
MikeyE
8

Musisz użyć df.shifttutaj.
df.shift(i)przesuwa w dół całą ramkę danych o ijednostki.

A więc za i = 1:

Wejście:

    x1   x2  
0  206  214  
1  226  234  
2  245  253  
3  265  272    
4  283  291

Wynik:

    x1   x2
0  Nan  Nan   
1  206  214  
2  226  234  
3  245  253  
4  265  272 

Więc uruchom ten skrypt, aby uzyskać oczekiwany wynik:

import pandas as pd

df = pd.DataFrame({'x1': ['206', '226', '245',' 265', '283'],
                   'x2': ['214', '234', '253', '272', '291']})

print(df)
df['x2'] = df['x2'].shift(1)
print(df)
Ayush Jain
źródło
3
Witamy w stackoverflow. Twoja odpowiedź będzie bardziej pomocna, jeśli podasz wyjaśnienie, jak należy jej używać.
Simon.SA
1
znowu straciłeś jeden rząd nr 5, którego OP wyraźnie chce
KIC
6

Pozwala zdefiniować ramkę danych z Twojego przykładu przez

>>> df = pd.DataFrame([[206, 214], [226, 234], [245, 253], [265, 272], [283, 291]], 
    columns=[1, 2])
>>> df
     1    2
0  206  214
1  226  234
2  245  253
3  265  272
4  283  291

Następnie możesz manipulować indeksem drugiej kolumny za pomocą

>>> df[2].index = df[2].index+1

i na koniec ponownie połącz pojedyncze kolumny

>>> pd.concat([df[1], df[2]], axis=1)
       1      2
0  206.0    NaN
1  226.0  214.0
2  245.0  234.0
3  265.0  253.0
4  283.0  272.0
5    NaN  291.0

Być może nie jest szybkie, ale łatwe do odczytania. Rozważ ustawienie zmiennych dla nazw kolumn i rzeczywistego wymaganego przesunięcia.

Edycja: Generalnie przesunięcie jest możliwe przez df[2].shift(1)już opublikowane, ale spowodowałoby to odcięcie przeniesienia.

Kay Wittig
źródło
Zastanawiam się, czy istnieje szybki sposób, aby to zrobić, i używając indeksu daty, Zasadniczo chcesz przesunąć bez obcinania naszej serii, a zatem musisz określić dodatkowe wartości indeksu. w przypadku przesunięcia o jeden można powiedzieć coś w rodzaju series.shift (-1, fill = [datetime (<some date>)]). Czy coś takiego jest możliwe? Ach, znalazłem to tutaj stackoverflow.com/questions/36042804/…
OldSchool
5

Jeśli nie chcesz stracić kolumn, które przesuwasz poza koniec ramki danych, po prostu dodaj najpierw wymaganą liczbę:

    offset = 5
    DF = DF.append([np.nan for x in range(offset)])
    DF = DF.shift(periods=offset)
    DF = DF.reset_index() #Only works if sequential index
David Ferris
źródło
3

Przypuszczam, że import

import pandas as pd
import numpy as np

Najpierw dołącz nowy wiersz z NaN, NaN,...na końcu DataFrame ( df).

s1 = df.iloc[0]    # copy 1st row to a new Series s1
s1[:] = np.NaN     # set all values to NaN
df2 = df.append(s1, ignore_index=True)  # add s1 to the end of df

Stworzy nowy DF df2. Może jest bardziej elegancki sposób, ale to działa.

Teraz możesz to zmienić:

df2.x2 = df2.x2.shift(1)  # shift what you want
martin-voj
źródło
2

Próbując odpowiedzieć na problem osobisty i podobny do twojego, znalazłem na Pandas Doc to, co myślę, że odpowiedziałoby na to pytanie:

DataFrame.shift ( period = 1, freq = None, axis = 0) Przesuń indeks o żądaną liczbę okresów z opcjonalnym czasem freq

Uwagi

Jeśli określono częstotliwość, wartości indeksu są przesuwane, ale dane nie są ponownie wyrównywane. To znaczy, użyj freq, jeśli chcesz rozszerzyć indeks podczas przesuwania i zachować oryginalne dane.

Mam nadzieję, że pomogę w przyszłych pytaniach w tej sprawie.

Tha_franklin
źródło
0

Oto jak to robię:

df_ext = pd.DataFrame(index=pd.date_range(df.index[-1], periods=8, closed='right'))
df2 = pd.concat([df, df_ext], axis=0, sort=True)
df2["forecast"] = df2["some column"].shift(7)

Zasadniczo generuję pustą ramkę danych z żądanym indeksem, a następnie po prostu łączę je razem. Ale naprawdę chciałbym zobaczyć to jako standardową funkcję w pandach, więc zaproponowałem ulepszenie pand.

KIC
źródło