Comment déplacer une colonne dans Pandas DataFrame

101

Je voudrais déplacer une colonne dans un Pandas DataFrame, mais je n'ai pas été en mesure de trouver une méthode pour le faire à partir de la documentation sans réécrire l'ensemble du DF. Quelqu'un sait-il comment le faire? Trame de données:

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

Sortie désirée:

##    x1   x2
##0  206  nan
##1  226  214
##2  245  234
##3  265  253
##4  283  272
##5  nan  291
racine
la source
3
cela devrait vraiment être un drapeau optionnel pour la fonction de décalage
KIC

Réponses:

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
la source
9
Le résultat est manquant ## 5. Existe-t-il un moyen simple dans les pandas d'étendre l'index lors de l'utilisation de shift?
Waylon Walker
@WaylonWalker C'est ce qu'on appelle rouler dans numpy:df['x2'] = np.roll(df['x2'], 1)
ayhan
1
Est-ce que quelqu'un a compris cela? # 5 est toujours manquant
Kritz
Je dois décaler 100 colonnes de la même manière, comment puis-je créer une boucle for?
Vincent Roye
2
@Johan avez-vous essayé d'ajouter une ligne vide à la fin avant de la décaler?
MikeyE
8

Vous devez utiliser df.shiftici.
df.shift(i)décale l'ensemble de la trame de données par iunités vers le bas.

Donc, pour i = 1:

Contribution:

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

Production:

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

Alors, exécutez ce script pour obtenir la sortie attendue:

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
la source
3
Bienvenue dans stackoverflow. Votre réponse sera plus utile si vous expliquez comment elle doit être utilisée.
Simon.SA
1
encore une fois, vous avez perdu une ligne # 5 que l'OP veut clairement
KIC
6

Permet de définir le dataframe à partir de votre exemple en

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

Ensuite, vous pouvez manipuler l'index de la deuxième colonne en

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

et enfin re-combiner les colonnes simples

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

Peut-être pas rapide mais simple à lire. Envisagez de définir des variables pour les noms de colonne et le décalage réel requis.

Edit: Généralement, le décalage est possible par df[2].shift(1)comme déjà affiché, mais cela couperait le report.

Kay Wittig
la source
Je me demande s'il existe un moyen rapide de le faire, et en utilisant un index de date, vous voulez essentiellement décaler sans tronquer notre série, et vous devez donc spécifier les valeurs d'index supplémentaires. pour un décalage de un, vous diriez quelque chose comme series.shift (-1, fill = [datetime (<some date>)]). Est-ce que quelque chose comme ça est possible? Ah trouvé ici stackoverflow.com/questions/36042804/…
OldSchool
5

Si vous ne voulez pas perdre les colonnes que vous déplacez au- delà de la fin de votre dataframe, ajoutez simplement le nombre requis en premier:

    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
la source
3

Je suppose que les importations

import pandas as pd
import numpy as np

Ajoutez d'abord une nouvelle ligne avec NaN, NaN,...à la fin de 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

Cela créera un nouveau DF df2. Peut-être qu'il y a un moyen plus élégant mais cela fonctionne.

Vous pouvez maintenant le déplacer:

df2.x2 = df2.x2.shift(1)  # shift what you want
martin-voj
la source
2

En essayant de répondre à un problème personnel et similaire au vôtre, j'ai trouvé sur Pandas Doc ce que je pense répondre à cette question:

DataFrame.shift (périodes = 1, freq = None, axis = 0) Décale l'index du nombre de périodes souhaité avec une fréquence de temps optionnelle

Remarques

Si freq est spécifié, les valeurs d'index sont décalées mais les données ne sont pas réalignées. Autrement dit, utilisez freq si vous souhaitez étendre l'index lors du décalage et conserver les données d'origine.

J'espère aider les questions futures à ce sujet.

Tha_franklin
la source
0

Voici comment je fais:

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)

Fondamentalement, je génère une trame de données vide avec l'index souhaité, puis je les concatène simplement. Mais j'aimerais vraiment voir cela comme une fonctionnalité standard dans les pandas, j'ai donc proposé une amélioration pour les pandas.

KIC
la source