Pandas DataFrameで列をシフトする方法


100

Pandas DataFrameで列をシフトしたいのですが、ドキュメント全体からDF全体を書き換えずにそれを行う方法を見つけることができませんでした。誰でもそれを行う方法を知っていますか?データフレーム:

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

望ましい出力:

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

3
これは実際にはシフト機能へのオプションのフラグである必要があります
KIC

回答:


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
結果には## 5がありません。パンダでシフトを使用するときにインデックスを拡張する簡単な方法はありますか?
Waylon Walker

@WaylonWalkerそれは乱暴にローリングと呼ばれています:df['x2'] = np.roll(df['x2'], 1)
ayhan '25

1
誰かがこれを理解しましたか?#5はまだ足りない
クリッツ

同じように100列をシフトする必要がありますが、forループを作成するにはどうすればよいですか?
Vincent Roye、2018

2
@Johanは、シフトする前に最後に空の行を追加しようとしましたか?
MikeyE 2018年

8

df.shiftここで使用する必要があります。
df.shift(i)データフレーム全体を下にi単位でシフトします。

以下のため、そうi = 1

入力:

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

出力:

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

したがって、次のスクリプトを実行して、予期される出力を取得します。

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
Stackoverflowへようこそ。回答は、使用方法の説明を提供するとさらに役立ちます。
Simon.SA 2018年

1
再び、OPが明らかに必要とする1行#5を失いました
KIC

6

例からデータフレームを定義してみましょう

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

次に、2番目の列のインデックスを操作することができます

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

そして最後に単一の列を再結合します

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

おそらく速くはありませんが、読むのは簡単です。列名と必要な実際のシフトに変数を設定することを検討してください。

編集:一般的にシフトはdf[2].shift(1)すでに投稿されているように可能ですが、キャリーオーバーをカットオフします。


これを行う高速な方法はありますか?日付インデックスを使用しています。基本的に、系列を切り捨てずにシフトする必要があるため、追加のインデックス値を指定する必要があります。1つシフトする場合は、series.shift(-1、fill = [datetime(<some date>)])のようになります。このようなことは可能ですか?ああ、ここでそれを見つけたstackoverflow.com/questions/36042804/...
オールドスクール

5

データフレームの終わりを超えシフトした列を失いたくない場合は、最初に必要な数を追加するだけです。

    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

輸入だと思います

import pandas as pd
import numpy as np

最初にNaN, NaN,...、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

新しいDF df2を作成します。よりエレガントな方法があるかもしれませんが、これはうまくいきます。

これでシフトできます:

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

2

Pandas Docで見つけた個人的な問題と同様の問題に答えようとすると、この質問に答えると思います。

DataFrame.shift(periods = 1、freq = None、axis = 0)オプションの時間freqを使用して、インデックスを必要な期間数だけシフトします。

ノート

freqが指定されている場合、インデックス値はシフトされますが、データは再調整されません。つまり、シフト時にインデックスを拡張して元のデータを保持する場合は、freqを使用します。

この問題の将来の質問に役立つことを願っています。


0

これが私のやり方です:

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)

基本的に、目的のインデックスを持つ空のデータフレームを生成し、それらを連結します。しかし、これをパンダの標準機能として本当に見たいので、パンダへの拡張提案しました

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.