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_indexer
とcolumn_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つのポイントがあります:
- 出力には、
row_label_end
で指定された行が含まれます。これは、後で説明する.iloc
とは異なります。 - 複数の行を取得したい場合でも、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を超える各顧客のName
、Country
、および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番目の列の両方を返します。
この場合、表示される情報は各顧客の Name
と Age
です:
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
の違いが明確になったことを願っています。さらに学ぶために、次のステップをいくつかご紹介します: