Como deslocar uma coluna no Pandas DataFrame


101

Eu gostaria de mudar uma coluna em um Pandas DataFrame, mas não consegui encontrar um método para fazer isso na documentação sem reescrever todo o DF. Alguém sabe fazer isso? Quadro de dados:

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

Saída desejada:

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

3
este deve ser realmente um sinalizador opcional para a função shift
KIC

Respostas:


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
O resultado está faltando ## 5. Existe uma maneira fácil nos pandas de estender o índice ao usar shift?
Waylon Walker

@WaylonWalker Isso é chamado de rolling in numpy:df['x2'] = np.roll(df['x2'], 1)
ayhan

1
Alguém descobriu isso? # 5 ainda está faltando
Kritz de

Tenho que deslocar 100 colunas da mesma maneira, como posso fazer um loop for?
Vincent Roye,

2
@Johan você tentou adicionar uma linha vazia no final antes de deslocá-la?
MikeyE

8

Você precisa usar df.shiftaqui.
df.shift(i)desloca todo o dataframe por iunidades para baixo.

Então, para i = 1:

Entrada:

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

Resultado:

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

Portanto, execute este script para obter a saída esperada:

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
Bem-vindo ao stackoverflow. Sua resposta será mais útil se você fornecer alguma explicação de como ele deve ser usado.
Simon.SA

1
novamente, você perdeu uma linha # 5 que OP claramente deseja
KIC

6

Vamos definir o dataframe do seu exemplo por

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

Então você pode manipular o índice da segunda coluna

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

e finalmente recombinar as colunas únicas

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

Talvez não seja rápido, mas simples de ler. Considere definir variáveis ​​para os nomes das colunas e o deslocamento real necessário.

Editar: Geralmente, a mudança é possível df[2].shift(1)conforme já postado, porém isso cortaria o transporte.


Gostaria de saber se existe uma maneira rápida de fazer isso e, usando um índice de data, basicamente você deseja deslocar sem truncar nossa série e, portanto, deve especificar os valores de índice adicionais. para um deslocamento de um, você diria algo como series.shift (-1, fill = [datetime (<some date>)]). Algo assim é possível? Encontrei aqui stackoverflow.com/questions/36042804/…
OldSchool

5

Se você não quiser perder as colunas que ultrapassou o final do seu dataframe, basta anexar o número necessário primeiro:

    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

Suponho que importe

import pandas as pd
import numpy as np

Primeiro anexe uma nova linha com NaN, NaN,...no final 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

Isso criará um novo DF df2. Talvez haja uma maneira mais elegante, mas isso funciona.

Agora você pode mudá-lo:

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

2

Tentando responder a um problema pessoal e semelhante ao seu, encontrei no Pandas Doc o que acho que responderia a esta pergunta:

DataFrame.shift (períodos = 1, freq = Nenhum, eixo = 0) Índice de deslocamento pelo número desejado de períodos com uma frequência de tempo opcional

Notas

Se freq for especificado, os valores do índice serão alterados, mas os dados não serão realinhados. Ou seja, use freq se quiser estender o índice ao mudar e preservar os dados originais.

Espero ajudar futuras perguntas neste assunto.


0

É assim que eu faço:

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)

Basicamente, estou gerando um dataframe vazio com o índice desejado e, em seguida, apenas concatená-los. Mas eu realmente gostaria de ver isso como um recurso padrão nos pandas, então propus um aprimoramento para os pandas.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.