Come spostare una colonna in Pandas DataFrame


101

Vorrei spostare una colonna in un Panda DataFrame, ma non sono stato in grado di trovare un metodo per farlo dalla documentazione senza riscrivere l'intero DF. Qualcuno sa come farlo? DataFrame:

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

Uscita desiderata:

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

3
questo dovrebbe essere davvero un flag opzionale per la funzione shift
KIC

Risposte:


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

8
Il risultato manca ## 5. C'è un modo semplice nei panda per estendere l'indice quando si usa lo spostamento?
Waylon Walker

@WaylonWalker Si chiama rotolare in numpy:df['x2'] = np.roll(df['x2'], 1)
ayhan

1
Qualcuno l'ha capito? Manca ancora il numero 5
Kritz

Devo spostare 100 colonne allo stesso modo, come posso creare un ciclo for?
Vincent Roye

2
@Johan hai provato ad aggiungere una riga vuota alla fine prima di spostarla?
MikeyE

8

Devi usare df.shiftqui.
df.shift(i)sposta l'intero dataframe di iunità verso il basso.

Quindi, per i = 1:

Ingresso:

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

Produzione:

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

Quindi, esegui questo script per ottenere l'output previsto:

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)

3
Benvenuto in stackoverflow. La tua risposta sarà più utile se fornisci qualche spiegazione su come dovrebbe essere utilizzata.
Simon.SA

1
di nuovo hai perso una riga n. 5 che OP chiaramente vuole
KIC

6

Definiamo il dataframe dal tuo esempio di

>>> 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

Quindi potresti manipolare l'indice della seconda colonna di

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

e infine ricombinare le singole colonne

>>> 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

Forse non veloce ma semplice da leggere. Considerare l'impostazione delle variabili per i nomi delle colonne e lo spostamento effettivo richiesto.

Modifica: generalmente lo spostamento è possibile df[2].shift(1)come già pubblicato, tuttavia ciò interromperà il riporto.


Mi chiedo se esista un modo veloce per farlo, e utilizzando un indice di data, in sostanza vuoi spostare senza troncare la nostra serie, e quindi devi specificare i valori di indice aggiuntivi. per uno spostamento di uno, diresti qualcosa come series.shift (-1, fill = [datetime (<some date>)]). È possibile qualcosa di simile? Ah trovato qui stackoverflow.com/questions/36042804/...~~V~~singular~~3rd
OldSchool

5

Se non vuoi perdere le colonne che sposti oltre la fine del tuo dataframe, aggiungi semplicemente prima il numero richiesto:

    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

3

Suppongo che le importazioni

import pandas as pd
import numpy as np

Prima aggiungi una nuova riga con NaN, NaN,...alla fine di 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

Creerà un nuovo DF df2. Forse c'è un modo più elegante ma funziona.

Ora puoi spostarlo:

df2.x2 = df2.x2.shift(1)  # shift what you want

2

Cercando di rispondere a un problema personale e simile al tuo ho trovato su Pandas Doc quello che penso risponderebbe a questa domanda:

DataFrame.shift (periodi = 1, freq = Nessuno, asse = 0) Sposta l'indice del numero di periodi desiderato con una frequenza temporale opzionale

Appunti

Se viene specificato freq, i valori dell'indice vengono spostati ma i dati non vengono riallineati. Cioè, usa freq se desideri estendere l'indice durante lo spostamento e conservare i dati originali.

Spero di aiutare le future domande in questa materia.


0

Ecco come lo faccio:

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)

Fondamentalmente sto generando un dataframe vuoto con l'indice desiderato e poi semplicemente concatenarli insieme. Ma mi piacerebbe davvero vederlo come una caratteristica standard nei panda, quindi ho proposto un miglioramento ai panda.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.