1. ホーム
  2. python

[解決済み] Pandasはどのようなルールでビューとコピーを生成するのでしょうか?

2022-04-26 18:30:30

質問

データフレームからの選択が元のデータフレームのコピーであるか、元のデータフレームに対するビューであるかを決定する際に、Pandasが使用するルールについて混乱しています。

もし、例えば

df = pd.DataFrame(np.random.randn(8,8), columns=list('ABCDEFGH'), index=range(1,9))

というのはわかりますが query はコピーを返すので、次のようなものは

foo = df.query('2 < index <= 5')
foo.loc[:,'E'] = 40

は、元のデータフレームに影響を与えません。 df . また、スカラーまたは名前付きスライスがビューを返すことも理解しているので、これらに対する代入、たとえば

df.iloc[3] = 70

または

df.ix[1,'B':'E'] = 222

を変更します。 df . でも、もっと複雑なケースになると迷いますね。例えば

df[df.C <= df.B] = 7654321

変化 df しかし

df[df.C <= df.B].ix[:,'B':'E']

はしません。

Pandasが使っている簡単なルールで、私が見逃しているだけなのでしょうか?特に、(上記の最後の例で試みているように)特定のクエリを満たすデータフレーム内のすべての値(または値のサブセット)を変更するにはどうしたらよいでしょうか?


注:これは この質問 を読みました。 ドキュメント ということなのでしょうが、どうも釈然としません。このトピックに関する "Related" の質問にも目を通しましたが、Pandas が使用している単純なルールと、それを適用して - たとえば、特定のクエリを満たすデータフレーム内の値(または値のサブセット)を変更するにはどうすればよいかがまだわかっていません。

解決するには?

ここにルールがあり、その後にオーバーライドします。

  • すべての操作でコピーを生成

  • もし inplace=True を指定すると、インプレースで変更されます。

  • を設定するインデクサ。 .loc/.iloc/.iat/.at はインプレースで設定します。

  • 単一型オブジェクトを取得するインデクサは、ほとんどの場合ビューです (メモリレイアウトによっては、これが信頼できない理由です)。これは主に効率化のためです。(上記の例は .query これは 常に で評価されたコピーを返します。 numexpr )

  • 多重型付けされたオブジェクトを取得するインデクサは、常にコピーである。

の例では chained indexing

df[df.C <= df.B].loc[:,'B':'E']

は動作保証外です。 決して を実行します)。

その代わり、こうしてください。

df.loc[df.C <= df.B, 'B':'E']

このように より速く で、常に動作します。

連鎖したインデックスは2つの別々のPython操作であるため、pandasが確実に傍受することはできません(頻繁に SettingWithCopyWarning が、これも100%検出できるわけではありません)。その デブ・ドックス ご指摘の通り、もっと詳しい説明があります。