1. ホーム
  2. python

[解決済み] Pandas/Pythonでカラムのフィルタリングにlocを使うのと角括弧だけを使うのでは何が違うのでしょうか?

2022-08-15 03:18:34

質問

Pandas DataFrameのカラムを選択する方法として、3つの方法があることに気づきました。

最初の方法は、locを使用して列を選択する方法です。

df_new = df.loc[:, 'col1']

第二の方法 - よりシンプルで高速に見えます。

df_new = df['col1']

第3の方法 - 最も便利な方法です。

df_new = df.col1

この3つの方法に違いはあるのでしょうか?私はそうは思いません。それなら、3番目の方法を使う方がいいと思います。

同じことをするのに3つの方法があるように見えるのが不思議です。

どのように解決するのですか?

以下の状況では、同じ動作をします。

  1. 単一のカラムを選択する ( df['A'] と同じです。 df.loc[:, 'A'] -> A列を選択します)
  2. カラムのリストを選択する ( df[['A', 'B', 'C']] と同じです。 df.loc[:, ['A', 'B', 'C']] -> 列A,B,Cを選択します)
  3. 行によるスライス ( df[1:3] と同じです。 df.iloc[1:3] ->は、1行目と2行目を選択します。ただし、行をスライスする際に loc でスライスした場合、代わりに iloc があると仮定すると、1,2,3 行目が表示されます。 RangeIndex . 詳細を見る ここで .)

しかし [] は以下の状況では動作しません。

  1. 1つの行を選択するのに df.loc[row_label]
  2. 行のリストを選択するには df.loc[[row_label1, row_label2]]
  3. 列をスライスするには df.loc[:, 'A':'C']

この3つは [] . さらに重要なことは、もし選択が行と列の両方を含むなら、割り当てが問題になります。

df[1:3]['A'] = 5

これは1行目と2行目を選択し、リターンオブジェクトの列 'A' を選択して値5を代入しています。問題は、リターンオブジェクトがコピーである可能性があるため、実際のDataFrameが変更されない可能性があることです。このため SettingWithCopyWarningが発生します。 . この割り当てを行う正しい方法は

df.loc[1:3, 'A'] = 5

とは .loc を使えば、元のDataFrameを変更することが保証されます。また、カラムをスライスすることも可能です ( df.loc[:, 'C':'F'] )、単一の行を選択する ( df.loc[5] ) 、そして行のリストを選択する ( df.loc[[1, 2, 5]] ).

また、この二つは同時にAPIに含まれていないことに注意してください。 .loc は、より強力で明示的なインデクサとしてずっと後に追加されました。参照 unutbuの回答 をご覧ください。


注意: カラムの取得に [] 対して . は全く別の話題です。 . は便宜上存在するだけです。これは、名前が有効な Python 識別子であるカラムにのみアクセスできます(つまり、スペースを含むことはできず、数字で構成することもできません...)。Series/DataFrame のメソッドと名前が衝突する場合は使用できません。また、存在しないカラムにも使用できません(例えば、代入された df.a = 1 という代入は、列が存在しない場合は機能しません。 a ). その他に .[] は同じです。