PandasにおけるIlocとLoc:例を用いたガイド

Pandasを学ぶとき、みんなが解決しようとしている厄介なことの一つは、.loc.ilocの違いです。

この混乱を終わらせ、これら二つのメソッドの違いを明確にしましょう。たくさんの例を挙げるので、ブログの終わりまでにはその違いがずっと明確になることを願っています。

Pandasにおける.locと.ilocとは?

.loc.ilocはどちらもPandas DataFrameの重要な属性であり、特定のデータの部分集合を選択するために使用されます。これらの目的は、DataFrame全体ではなく、DataFrameの特定の部分にアクセスし、操作を可能にすることです。

特徴

.loc

.iloc

構文

df.loc[row_indexer, column_indexer]

df.iloc[row_indexer, column_indexer]

インデックス付け方法

ラベルベースのインデックス付け

位置ベースのインデックス付け

参照用途で使用

行と列のラベル(名前)

行と列の数値インデックス(0から始まる)

表からわかるように、構文は非常に似ています。違いは、row_indexercolumn_indexer引数の使用方法にあります。これは、2つのメソッドがデータのインデックス付けに異なるアプローチを提供しているためです。つまり、.locはラベル名に基づいてインデックス付けを行い、.ilocは行と列の数値位置インデックスを引数として受け取ります。

それでは、.locから詳細に調査していきましょう。

.locを使用してラベルで選択する

概念を説明するために、仮想の顧客データベースを考えてみましょう。このDataFrameはdfと呼ばれ、Customer IDが行インデックスを表しています:

Customer ID

Name

Country

Region

Age

C123

John Doe

United States

North America

67

C234

Petra Müller

Germany

Europe

51

C345

アリ・カーン

パキスタン

アジア

19

C456

マリア・ゴンザレス

メキシコ

北アメリカ

26

C567

デイビッド・リー

中国

アジア

40

を選択する主な方法は4つあります。これには次のものが含まれます:

  • 単一の行を選択する
  • 複数の行を選択する
  • 行のスライスを選択する
  • 条件付き行の選択

.locを使用して単一の行を選択する

単一の行を選択するには、取得したい行のラベルをrow_indexerとして使用します。したがって、構文は次のようになります:df.loc['row_label']。これを使用して、顧客Ali Khanの情報をすべて表示しましょう:

df.loc['C345']

C345

 

名前

Ali Khan

パキスタン

地域

アジア

年齢

19

.locを使用して複数の行を選択する

順番に並んでいない複数の行を選択したい場合、row_indexer引数として行ラベルのリストを渡す必要があります。つまり、通常の.loc構文用とラベルリスト用の2組の角かっこを使用する必要があります。

df.loc[['row_label_1', 'row_label_2']]という行は、リストで指定されたdfの2つの行を返します。たとえば、Ali KhanだけでなくDavid Leeの情報も知りたいとします。

df.loc[['C345', 'C567']]

顧客ID

名前

地域

年齢

C345

アリ・カーン

パキスタン

アジア

19

C567

デイビッド・リー

中国

アジア

40

行を.locを使って選択する

最初と最後の行ラベルをコロンで区切って渡すことで行の範囲を選択できます:df.loc['row_label_start':'row_label_end']。データフレームの最初の4行をこのように表示することができます:

df.loc['C123' : 'C456']

顧客ID

名前

地域

サインアップ日

C123

ジョン・ドウ

アメリカ合衆国

北アメリカ

67

C234

ペトラ・ミュラー

ドイツ

ヨーロッパ

51

C345

アリ・カーン

パキスタン

アジア

19

C456

マリア・ゴンザレス

メキシコ

北アメリカ

26

ここで留意すべき2つのポイントがあります:

  1. 出力には、row_label_endで指定された行が含まれます。これは、後で説明する.ilocとは異なります。
  2. 複数の行を取得したい場合でも、1組の角括弧のみを使用します。さまざまな行を指定するためにリストを使用しないため、2組の角括弧を使用するとSyntaxErrorが返されます。

条件付き選択による行の取得 .loc

条件式に基づいて行を返すこともできます。特定の条件を満たすかどうかで全ての行をフィルタリングし、満たす行のみを表示します。

対応する構文はdf.loc[conditional_expression]であり、conditional_expressionは特定の列における許可された値に関する文です。

数値以外のデータ(名前など)を含む列では、値の間に順序がないため、等しいまたは等しくない演算子のみを使用できます。たとえば、アジア以外の顧客のすべての行を返すことができます:

df.loc[df['Region'] != 'Asia']

顧客ID

名前

地域

年齢

C123

ジョン・ドウ

アメリカ合衆国

北アメリカ

67

C234

ペトラ・ミューラー

ドイツ

ヨーロッパ

51

C456

マリア・ゴンザレス

メキシコ

北アメリカ

26

単一の列を.locを使って選択する

列を選択するには、row_indexer引数の後に続くcolumn_indexer引数を指定する必要があります。column_indexerのみを指定したい場合は、すべての行を返し、列のみをフィルタリングすることを示す必要があります。どのようにそれを行うか見てみましょう!

単一の列を選択するには、該当する列のラベルでcolumn_indexerを指定します。すべての行を取得するには、シンプルなコロンでrow_indexerを指定する必要があります。次のような構文に到達します:df.loc[:, 'column_name']

各顧客の名前を表示してみましょう:

df.loc[:, 'Name']

顧客ID

名前

C123

ジョン・ドー

C234

ペトラ・ミュラー

C345

アリ・カーン

C456

マリア・ゴンザレス

C567

デイビッド・リー

複数の列を.locを使用して選択する

複数の行を選択するのと同様に、順番に従う必要のないDataFrameの複数の列を返す場合、列ラベルのリストを渡す必要があります:df.loc[:, [col_label_1, 'col_label_2']].

すべての顧客の年齢を最後の出力に追加したいと仮定すると、次のように動作します:

df.loc[:, ['Name', 'Age']]

顧客ID

名前

年齢

C123

ジョン・ドー

67

C234

ペトラ・ミュラー

51

C345

アリ・カーン

19

C456

マリア・ゴンザレス

26

C567

デビッド・リー

40

列のスライスを .loc を使って選択する

2つの列のラベルの間にコロンを入れることで、指定した2つの列の間にあるすべての列を順番に選択できます。終端列も含まれているため、col_endという名前の列も、標準構文で選択されます。これは以下の通りです:df.loc[:, 'col_start':'col_end']

もし私たちが顧客の名前、および地域に興味があるなら、私たちのコードラインは次のようになります:

df.loc[:, 'Name':'Region']

顧客ID

名前

地域

C123

ジョン・ドー

アメリカ合衆国

北アメリカ

C234

ペトラ・ミュラー

ドイツ

ヨーロッパ

C345

アリ・カーン

パキスタン

アジア

C456

マリア・ゴンザレス

メキシコ

北アメリカ

C567

デイビッド・リー

中国

アジア

行と列の選択を .loc を使用して組み合わせることができます

行インデクサーと列インデクサーの両方を指定することも可能です。これを使用して、DataFrameから1つの情報、つまり1つのセルを取得できます。これを行うには、次の構文を使用して1つの行と1つの列を指定します:df.loc['row_label', 'column_name']

より便利なケースは、私たちが興味を持っている行と列のセットに正確に焦点を当てたサブDataFrameを返すことです。インデクサーの両方を角括弧を使用してリストとして指定することも、コロンを使用してスライスとして指定することも可能であり、さらに行の選択のための条件式と組み合わせることもできます。

以下は、Ageが30を超える各顧客のNameCountry、およびRegionを返す例です:

df.loc[df['Age'] > 30, 'Name':'Region']

顧客ID

名前

地域

C123

ジョン・ドウ

アメリカ合衆国

北アメリカ

C234

ペトラ・ミューラー

ドイツ

ヨーロッパ

C567

デビッド・リー

中国

アジア

整数位置による選択: .ilocの使用

.ilocはラベルではなく位置によって選択します。.ilocの標準的な文法は次のようになります: df.iloc[row_indexer, column_indexer]。注意すべき特別な点が2つあります:

  • 0から始まるカウント: 最初の行と列はインデックス0を持ち、2番目はインデックス1、などです。
  • 範囲の終了値の排他性: スライスを使用する場合、コロンの後に指定された行または列は選択に含まれません。

.ilocを使用して単一の行を選択する

単一の行は、行インデックス番号を表す整数をrow_indexerとして使用することで選択できます。.locでラベル文字列を入力するのではなく整数を入力しているため、引用符は必要ありません。DataFrame dfの最初の行を返すには、df.iloc[0]を入力します。

私たちの例のDataFrameでは、このコード行はジョン・ドーの情報を返します:

df.iloc[0]

C123

 

名前

John Doe

アメリカ合衆国

地域

北アメリカ

年齢

67

.ilocを使用して複数の行を選択する

.ilocで複数の行を選択する方法は、.locと同じです。行インデックスの整数を角かっこ内のリストで入力します。構文は次のようになります:df.iloc[[0, 3, 4]]。

顧客テーブルのそれぞれの出力は以下のようになります:

df.iloc[[0, 3, 4]]

顧客ID

名前

地域

年齢

C123

John Doe

アメリカ合衆国

北アメリカ

67

C456

マリア・ゴンザレス

メキシコ

北アメリカ

26

C567

デイビッド・リー

中国

アジア

40

`.iloc`を使用して行のスライスを選択する

行のスライスを選択するには、指定された2つの行インデックス整数の間にコロンを使用します。今、前述の排他性に注意を払わなければなりません。

この概念を説明する例として、df.iloc[1:4]という行を取ることができます。インデックス番号1は2番目の行を意味するため、スライスはそこから始まります。インデックス整数4は5番目の行を表しますが、.ilocはスライス選択に対して包括的ではないため、出力にはこの前の全行が含まれます。したがって、2番目、3番目、4番目の行が返されます。

この行が正常に機能していることを証明しましょう:

df.iloc[1:4]

顧客ID

名前

地域

年齢

C234

ペトラ・ミュラー

ドイツ

ヨーロッパ

51

C345

アリ・カーン

パキスタン

アジア

19

C456

マリア・ゴンザレス

メキシコ

北アメリカ

26

列を .iloc を使用して選択する

列を選択する際の論理は、これまで学んできたことに従います。単一の列、複数の列、および列のスライスについてどのように機能するか見てみましょう。

.locと同様に、column_indexerに進む前にrow_indexerを指定することが重要です。すべての行に対してdfの第3列の値を取得するには、df.iloc[:, 2]と入力します。

Regionは私たちのDataFrameの第3列なので、このコード行の結果として取得されます:

df.iloc[:, 2]

顧客ID

地域

C123

北アメリカ

C234

ヨーロッパ

C345

アジア

C456

北アメリカ

C567

アジア

複数の列を .iloc で選択する

複数の列を選択するには、整数のリストを column_indexer として再度入力できます。行 df.iloc[:, [0, 3]] は、最初と4番目の列の両方を返します。

この場合、表示される情報は各顧客の NameAge です:

df.iloc[:, [0, 3]]

顧客ID

名前

年齢

C123

ジョン・ドー

67

C234

ペトラ・ミューラー

51

C345

アリ・カーン

19

C456

マリア・ゴンザレス

26

C567

デイビッド・リー

40

列のスライスを .iloc で選択する

スライス選択における.ilocの論理は、row_indexerのそれに従います。コロンの後の整数で示される列は出力に含まれません。2番目と3番目の列を取得するには、コード行は次のようになります:df.iloc[:, 1:3]

以下の行は、私たちが顧客について持っているすべての地理情報を返します:

df.iloc[:, 1:3]

顧客ID

地域

C123

アメリカ合衆国

北アメリカ

C234

ドイツ

ヨーロッパ

C345

パキスタン

アジア

C456

メキシコ

北アメリカ

C567

中国

アジア

行と列の選択を組み合わせるための .iloc

私たちは .iloc について学んだことをまとめて、行と列の選択を組み合わせることができます。再度、単一のセルを返すこともサブデータフレームを返すことも可能です。行3と列4の交差点にある単一のセルを返すには、df.iloc[2, 3] と入力します。

.loc と同様に、インデクサーをリストとして角括弧を使用して指定することも、コロンを使用してスライスとして指定することもできます。条件式を使用して行を選択したい場合、それは技術的には .iloc でも可能ですが、お勧めしません。ラベル名と .loc を使用する方が、通常ははるかに直感的でエラーが発生しにくいです。

この最後の例では、データフレームの最初、2番目、5番目の行に対して 地域年齢 を表示します:

df.iloc[[0,1,4], 1:4]

顧客ID

地域

年齢

C123

アメリカ合衆国

北アメリカ

67

C234

ドイツ

ヨーロッパ

51

C567

中国

アジア

40

.iloc vs .loc: どちらを使用するべきか

一般的に、メソッドの選択はDataFrameの知識に依存するというシンプルなルールがあります:

  • .locを使用するのは、行/列のラベル(名前)を知っている場合です。
  • 整数位置を知っている場合は、.ilocを使用してください。行/列の

いくつかのシナリオでは、その性質により.locまたは.ilocが有利です。例えば、行や列を繰り返し処理する際、ラベルよりも整数を使用する方が簡単で直感的です。すでに述べたように、列の値に基づいて行をフィルタリングする場合、列ラベル名を使用する方がエラーが発生しにくいです。

.locを好むシナリオ

.ilocを好むシナリオ

あなたのDataFrameには意味のあるインデックス/列名があります。

位置に基づいて行/列を繰り返しています。

列の値に基づいて条件でフィルターをかける必要があります。

インデックス/列名はあなたのタスクには関係ありません。

KeyError、NameError、およびIndex Errorは.locおよび.ilocと共に発生します

考えられる問題を見てみましょう。.locを使用する際の一般的な落とし穴は、KeyErrorに直面することです。このエラーは、DataFrame内に存在しない行または列のラベルにアクセスしようとしたときに発生します。これを避けるためには、使用するラベルが正確で、DataFrame内の既存のラベルと一致していることを常に確認し、タイプミスがないかを再確認する必要があります。

さらに、.locを使用して指定されたラベルには常に引用符を使用することが重要です。それを忘れるとNameErrorが返されます。

インデックスエラー(IndexError)は、.ilocを使用する際に、整数の位置を指定した結果、それがDataFrameのインデックスの有効範囲を超えている場合に発生することがあります。これは、アクセスしようとしているインデックスが存在しない場合に起こります。例えば、DataFrameの行数や列数を超えている場合や、負の値である場合です。このエラーを防ぐためには、DataFrameの次元を確認し、有効範囲内の適切なインデックス値を使用してください。

結論

このブログが役に立ち、.loc.ilocの違いが明確になったことを願っています。さらに学ぶために、次のステップをいくつかご紹介します:

Source:
https://www.datacamp.com/tutorial/loc-vs-iloc