inplace = Trueを理解する


108

pandasライブラリには、次のステートメントのように、オブジェクトをインプレースで変更するオプションが何度もあります。

df.dropna(axis='index', how='all', inplace=True)

何が返されるのか、inplace=True渡されたときとオブジェクトが渡されたときのオブジェクトの処理方法に興味がありますinplace=False

すべての操作はselfいつ変更されinplace=Trueますか?そして、andinplace=Falseなどの新しいオブジェクトがすぐに作成されて返されるのはいつですか?new_df = selfnew_df


14
はい、inplace=TruereturnsNone inplace=Falseは、操作が実行されたオブジェクトのコピーを返します。ドキュメントはこれについてかなり明確です、特定の部分と混同している何かがありますか?特別にIf True, do operation inplace and return None.
EdChum

DataFrameオブジェクトをサブクラス化していますが、マージなどの操作では、インプレースで実行できないようです...self = self.merge(new_df, how='left', on='column2' 自己を再割り当てできるかどうかわかりません
Aran

1
DataFrame.mergeinplace引数がないのは正しいです。DataFrameを返すため、再割り当てに問題はありません。
JAV 2017年

誰かがリソース消費の観点からそれを使用することの利点を強調することもできますか?
markroxor

2
@markroxor本当に多くはありません。場合inplaceによっては、結果のコピーを実際に返す必要がないため、アクションが少し速くなることがあります。しかし、それはそれについてです。それを使用しない理由は他にもたくさんあります。
cs 9519

回答:


99

ときにinplace=True渡され、データが(それは何も返しません)場所に名前が変更されたので、あなたが使用したいです:

df.an_operation(inplace=True)

ときにinplace=False渡され、実行する操作(これはそれほど必要ではなく、デフォルト値です)、あなたが使用したいので、オブジェクトのコピーを返します。

df = df.an_operation(inplace=False) 

inplaceこれは既存のデータを変更するメソッドのオプションにすぎず、データを「再形成」するメソッドのオプションではないと考えるのは正しいでしょうか。たとえば、既存のインデックスに値を適用するため、.set_index(inplace = True)はできますが、前の配列には存在しなかった余分な行がDataFrameに作成される可能性があるため、.reindex(inplace = True)はできません。 ?
ac24 2018年

4
このメソッド.dropna()inplace=Trueデータフレームを受け入れ、最も確実に再形成できるため、いいえ。
jorijnsmit

3
ここでは注意する必要があります。@ ac24は実際には多かれ少なかれ正しいです。ながらdropnaリターン異なる形状のデータフレームは、実際に、基礎となるデータを再形成しない-それは単にその上にマスク(戻りinplace=False恐れにつながることができ)、 SettingWithCopyWarning。古い値の配列への参照がなくなった場合にのみ、パンダはマスクに従って形状を変更します。より良い経験則は次のinplaceとおりです。操作で値の新しいバッキングndarrayを割り当てる必要がない場合に使用できます。
BallpointBen

49

パンダでは、インプレース= Trueは有害であると見なされますか?

TLDR; はい、そうです。

  • inplace、名前が示すものとは逆に、コピーの作成を妨げないことが多く、(ほとんど)パフォーマンス上の利点はありません。
  • inplace メソッドチェーンでは機能しません
  • inplace は初心者によくある落とし穴なので、このオプションを削除するとAPIが簡素化されます

このパラメータはほとんど目的を果たさないため、設定することはお勧めしません。引数をAPI全体で非推奨にすることを提案しているこのGitHubの問題を参照してくださいinplace

使用inplace=Trueすると、コードがより効率的または最適化されるというのはよくある誤解です。実際には、を使用してもパフォーマンス上のメリットまったくありませんinplace=True。インプレースバージョンとアウトオブプレースバージョンの両方で、とにかくデータのコピーが作成され、インプレースバージョンでは自動的にコピーが割り当てられます。

inplace=True初心者によくある落とし穴です。たとえばSettingWithCopyWarning:をトリガーできます。

df = pd.DataFrame({'a': [3, 2, 1], 'b': ['x', 'y', 'z']})

df2 = df[df['a'] > 1]
df2['b'].replace({'x': 'abc'}, inplace=True)
# SettingWithCopyWarning: 
# A value is trying to be set on a copy of a slice from a DataFrame

DataFrame列で関数を呼び出すと、機能する場合と機能しinplace=True ない場合があります。これは、連鎖インデックスが含まれる場合に特に当てはまります。

上記の問題だけでは不十分であるかのように、メソッドチェーンinplace=True妨げます。の動作を対比

result = df.some_function1().reset_index().some_function2()

とは対照的に

temp = df.some_function1()
temp.reset_index(inplace=True)
result = temp.some_function2()

前者は、コードの編成と読みやすさを向上させるのに役立ちます。


もう1つの裏付けとなる主張は、のAPIset_axisが最近変更され、inplaceデフォルト値がTrueからFalseに切り替えられたことです。GH27600を参照してください。素晴らしい仕事の開発者!


1
確かには、inplace=Trueなどの連鎖で仕事をしませんが、それはあなたがそれを概念的にやっているのか理解で明らかです。個人的には、割り当てを避ける方が少しすっきりしていると思いますlist.sort。標準ライブラリからなどを削除することにも賛成ですか?
Chris_Rands

4
それは公正な比較ではないと思います。list.sortを使用することとsortedを使用することには明らかな利点がいくつかあります。同じことが他のインプレース関数にも当てはまります。ここには実際の利点はありません。パンダではメソッドチェーンがはるかに一般的であり、とにかくこの議論の非推奨の計画があります。
cs 9519

また、割り当てを回避する方が少しlist.append()すっきりしています。たとえば、pythonもインプレースですが、pandas df.appendはインプレースではありません(インプレースもサポートしていません)。これは、私を終わらせません。本当の利点が何であるかを理解するためだけに、私が知りたいのはそのためです-割り当てを回避する以外に、list.sortとsortedを使用することの明らかな利点は何ですか?そうでなければ、私はここに本当の利点があると思います-私は個人的にそれがより読みやすいと思う割り当てを避けることができます。
sdbbs

1
@sdbbslist.append()は既存のリストに追加されます。df.appendデータのコピーを作成し(5行でも500万行でもかまいません)、コピーに新しい行を追加して、それを返します。何がより理にかなっていると思いますか?df.append、については可能な限りAVOID。inplace = Trueを主張するのは良い例ではないと思います。また、関数がAPIに配置されているとは思いません。
cs 9520年

46

私の使い方は

# Have to assign back to dataframe (because it is a new copy)
df = df.some_operation(inplace=False) 

または

# No need to assign back to dataframe (because it is on the same copy)
df.some_operation(inplace=True)

結論:

 if inplace is False
      Assign to a new variable;
 else
      No need to assign

5
こんにちは@Nabin、パンダと
ナンピーに

6

inplaceパラメータ:

df.dropna(axis='index', how='all', inplace=True)

Pandasおよび一般的な手段で:

1.パンダは元のデータのコピーを作成します

2 ....それに対していくつかの計算を行います

3 ....結果を元のデータに割り当てます。

4 ....コピーを削除します。

以下の私の回答の残りの部分で読むことができるように、このパラメータ、つまりを使用する正当な理由がまだありますが、次のように、inplace operationsより多くの問題が発生するため、可能であれば回避する必要があります。

1.コードのデバッグが難しくなります(実際には、SettingwithCopyWarningは、この考えられる問題について警告することを意味します)

2.メソッドチェーンとの競合


それで、私たちがまだそれを使うべきである場合さえありますか?

絶対そうです。パンダや巨大なデータセットを処理するためのツールを使用すると、一部のビッグデータがメモリ全体を消費する可能性があるという状況に簡単に直面する可能性があります。この望ましくない影響を回避するために、メソッドチェーンのようないくつかのテクニックを使用できます

(
    wine.rename(columns={"color_intensity": "ci"})
    .assign(color_filter=lambda x: np.where((x.hue > 1) & (x.ci > 7), 1, 0))
    .query("alcohol > 14 and color_filter == 1")
    .sort_values("alcohol", ascending=False)
    .reset_index(drop=True)
    .loc[:, ["alcohol", "ci", "hue"]]
)

これにより、コードがよりコンパクトになり(ただし、解釈とデバッグも困難になります)、チェーンされたメソッドが他のメソッドの戻り値と連携するため、メモリの消費量が少なくなり、入力データのコピー1つだけになります。この操作の後、元のデータメモリの消費量が2倍になることがはっきりとわかります。

または、inplaceパラメータを使用することもできます(解釈とデバッグも難しいですが)メモリ消費量は元のデータの2倍になりますが、この操作後のメモリ消費量は元のデータの1倍のままです。大きなメリット。


最終結論:

inplace巨大なデータを処理しない限り、パラメーターの使用は避け、パラメーターを引き続き使用する場合に発生する可能性のある問題に注意してください。


2

同じ変数に保存します

data["column01"].where(data["column01"]< 5, inplace=True)

別の変数に保存します

data["column02"] = data["column01"].where(data["column1"]< 5)

ただし、変数はいつでも上書きできます

data["column01"] = data["column01"].where(data["column1"]< 5)

参考:デフォルトでは inplace = False


1

関数を使用してPandasデータフレームに変更を加えようとするとき、データフレームに変更をコミットする場合は、「inplace = True」を使用します。したがって、次のコードの最初の行は、「df」の最初の列の名前を「Grades」に変更します。結果のデータベースを表示する場合は、データベースを呼び出す必要があります。

df.rename(columns={0: 'Grades'}, inplace=True)
df

変更をコミットせず、結果のデータベースを出力するだけの場合は、「inplace = False」(これもデフォルト値です)を使用します。したがって、実際には、変更がコミットされた元のデータベースのコピーが、元のデータベースを変更せずに印刷されます。

より明確にするために、次のコードは同じことを行います。

#Code 1
df.rename(columns={0: 'Grades'}, inplace=True)
#Code 2
df=df.rename(columns={0: 'Grades'}, inplace=False}

0

inplace=True 元のdfに変更を加えるかどうかに応じて使用されます。

df.drop_duplicates()

ドロップされた値のビューのみを作成し、dfは変更しません

df.drop_duplicates(inplace  = True)

値を削除し、dfに変更を加えます。

お役に立てれば。:)


0

inplace=True関数を不純にします。元のデータフレームを変更し、Noneを返します。その場合、あなたはDSLチェーンを壊します。ほとんどのデータフレーム関数は新しいデータフレームを返すため、DSLを便利に使用できます。お気に入り

df.sort_values().rename().to_csv()

inplace=Trueなしを返す関数呼び出しとDSLチェーンが壊れています。例えば

df.sort_values(inplace=True).rename().to_csv()

投げます NoneType object has no attribute 'rename'

Pythonの組み込みの並べ替えと並べ替えに似たもの。lst.sort()リターンNonesorted(lst)新しいリストを返します。

通常、inplace=True特別な理由がない限り使用しないでください。のような再割り当てコードを作成する必要がある場合df = df.sort_values()は、DSLチェーンに関数呼び出しを添付してみてください。

df = pd.read_csv().sort_values()...

適切なフォーマットで正確に機能するコードを提供することは、ユーザーがあなたの答えをより早く理解するのに本当に役立ちます。あなたに同じことをするように要求します。私はパンダの専門家ではないので、あなたの答えを再フォーマットすることはできませんが、強くお勧めします
AnandVaidya19年

0

パンダでの私の経験として、私は答えたいと思います。

'inplace = True'引数は、データフレームが変更を永続的に行う必要があることを表します。

    df.dropna(axis='index', how='all', inplace=True)

同じデータフレームを変更します(このパンダはインデックスでNaNエントリを見つけてドロップするため)。やってみたら

    df.dropna(axis='index', how='all')

pandasは、変更を加えたデータフレームを表示しますが、元のデータフレーム「df」は変更しません。


0

inplace = Trueを使用しない場合、またはinplace = Falseを使用する場合は、基本的にコピーが返されます。

たとえば、次のようになります。

testdf.sort_values(inplace=True, by='volume', ascending=False)

降順でソートされたデータで構造を変更します。

その後:

testdf2 = testdf.sort_values( by='volume', ascending=True)

testdf2をコピーにします。値はすべて同じですが、並べ替えが逆になり、独立したオブジェクトが作成されます。

次に、別の列を指定して、LongMAと言います。

testdf2.LongMA = testdf2.LongMA -1

testdfのLongMA列には元の値があり、testdf2にはデクリメントされた値があります。

計算のチェーンが拡大し、データフレームのコピーには独自のライフサイクルがあるため、違いを追跡することが重要です。


0

はい、パンダにはパラメータを持つ多くの関数がありますinplaceが、デフォルトではに割り当てられていFalseます。

したがって、元df.dropna(axis='index', how='all', inplace=False)のファイルを変更したくないと考えると、DataFrame代わりに、必要な変更を加えた新しいコピーが作成されます。

ただし、inplaceパラメータをに変更するとTrue

次にDataFrame、指定されたものに変更を加える代わりに、新しいコピーは必要ないと明示的に言うのと同じです。DataFrame

これにより、Pythonインタープリターは新しいものを作成しないように強制されますDataFrame

ただしinplace、結果を元のDataFrameに再割り当てすることで、パラメーターの使用を回避することもできます。

df = df.dropna(axis='index', how='all')

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