閉じる

Pandasのlocとilocの違いとは?正しい使い分けと具体的な記述例を解説

Pythonでデータ分析を行う際、ライブラリのPandasは欠かせないツールです。

その中でも、DataFrameやSeriesから特定のデータを抽出するための「loc」と「iloc」の使い分けは、初心者から中級者へステップアップする上で避けては通れない重要なポイントです。

一見すると似たような機能に見えるこれら2つの属性ですが、内部的な動作や指定方法は大きく異なります。

2026年現在のモダンなPandas環境においても、この違いを正確に理解していないと、意図しないデータの抽出や、予期せぬエラーに悩まされることになります。

本記事では、locとilocの根本的な違いから、実務で役立つ具体的な記述例、そしてパフォーマンスを意識した使い分けまで詳しく解説します。

locとilocの根本的な違い

Pandasのデータ抽出において、locilocはデータの「参照の仕方」が決定的に違います。

結論から述べると、locは「ラベル(名称)」に基づいてデータを指定し、ilocは「整数(位置)」に基づいてデータを指定します。

loc(Label-based indexing)の特徴

locは、インデックス名やカラム名といった「ラベル」を直接指定してデータにアクセスします。

人間が理解しやすい名前でデータを指定するため、コードの可読性が高まるというメリットがあります。

また、locのスライシング(範囲指定)は「終点を含む」という特徴があります。

これは、Pythonの標準的なリストのスライシングとは異なる挙動であるため、注意が必要です。

iloc(Integer-positional indexing)の特徴

一方でilocは、データの論理的な位置、つまり「0から始まる行番号・列番号」を指定してアクセスします。

データフレームのラベルが何であれ、先頭から数えて何番目かという情報だけでデータを抽出します。

こちらはilocのスライシングは「終点を含まない」という、標準的なPythonの仕様(range()など)と同じ挙動を示します。

locとilocの比較まとめ

まずは、両者の主な違いを比較表で確認しましょう。

特徴lociloc
指定方法ラベル名 (インデックス名、列名)整数位置 (0から始まるインデックス)
スライスの終点含まれる含まれない
条件抽出 (Boolean)直接利用可能基本的に不可 (配列形式に変換が必要)
主な用途特定の名前の列・行を取得したいとき機械学習の訓練データ作成時など位置ベースの処理

具体的なコード例による解説

ここからは、実際にPandasを動かしながら、それぞれの記述方法を詳しく見ていきましょう。

まずは、サンプルとなるDataFrameを作成します。

Python
import pandas as pd

# サンプルデータの作成
data = {
    'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
    'Age': [25, 30, 35, 40, 45],
    'City': ['Tokyo', 'Osaka', 'Nagoya', 'Fukuoka', 'Sapporo']
}
# インデックスを 'a', 'b', 'c', 'd', 'e' に設定
df = pd.DataFrame(data, index=['a', 'b', 'c', 'd', 'e'])

print(df)
実行結果
      Name  Age     City
a    Alice   25    Tokyo
b      Bob   30    Osaka
c  Charlie   35   Nagoya
d    David   40  Fukuoka
e      Eve   45  Sapporo

locを使ったデータ抽出

locを使って、特定の行や列を抽出してみます。

Python
# 'a'行のデータを取得
row_a = df.loc['a']

# 'a'行から'c'行までの 'Name' と 'Age' を取得
# 注意:'c'行も含まれる
subset_loc = df.loc['a':'c', ['Name', 'Age']]

print("--- row_a ---")
print(row_a)
print("\n--- subset_loc ---")
print(subset_loc)
実行結果
--- row_a ---
Name    Alice
Age        25
City    Tokyo
Name: a, dtype: object

--- subset_loc ---
      Name  Age
a    Alice   25
b      Bob   30
c  Charlie   35

loc['a':'c']と記述した場合、インデックスラベルが「c」である行までしっかり含まれていることがわかります。

ilocを使ったデータ抽出

次に、同じ範囲のデータをilocで抽出してみます。

Python
# 0行目(先頭行)のデータを取得
row_0 = df.iloc[0]

# 0行目から2行目(3行目の手前)までの、0列目から1列目を取得
# 注意:インデックス2(3行目)は含まれない
subset_iloc = df.iloc[0:2, 0:2]

print("--- row_0 ---")
print(row_0)
print("\n--- subset_iloc ---")
print(subset_iloc)
実行結果
--- row_0 ---
Name    Alice
Age        25
City    Tokyo
Name: a, dtype: object

--- subset_iloc ---
    Name  Age
a  Alice   25
b    Bob   30

iloc[0:2]の結果を見てわかる通り、指定した終点(2)は含まれず、0番目と1番目の行だけが抽出されています。

これがlocとilocの最も間違いやすい違いです。

実践的な使い分けシーン

どちらを使うべきか迷った際、判断基準となる代表的なケースを紹介します。

条件に基づく抽出(Boolean Indexing)

特定の条件に合致する行を抽出したい場合は、locを使用するのが一般的です。

Python
# Ageが35以上の行の、'Name' と 'City' を抽出
result = df.loc[df['Age'] >= 35, ['Name', 'City']]

print(result)
実行結果
      Name     City
c  Charlie   Nagoya
d    David  Fukuoka
e      Eve  Sapporo

ilocで行の条件指定を行う場合、ブール値のリストそのものは受け付けますが、カラム指定に列名(’Name’など)を使うことができません。

そのため、条件抽出にはlocが圧倒的に便利です。

データの更新

特定のセルを書き換えたい場合も、locilocを使用します。

Python
# ラベルを指定して更新
df.loc['a', 'Age'] = 26

# 位置を指定して更新
df.iloc[1, 1] = 31

print(df.head(2))
実行結果
    Name  Age   City
a  Alice   26  Tokyo
b    Bob   31  Osaka

2026年現在、Pandasでは「Chained Assignment(連鎖割り当て)」を避けることが強く推奨されています。

例えば df['Age']['a'] = 26 のような記述は、コピーに対して値を設定している可能性があり、元のデータフレームが更新されない「SettingWithCopyWarning」の原因となります。

locやilocを使って一段階でアクセスすることで、この問題を確実に回避できます。

2026年のモダンなTips:Copy-on-Writeとアクセス速度

Pandas 3.0以降、デフォルトとなったCopy-on-Write (CoW)の影響により、データの抽出効率と安全性が向上しています。

しかし、非常に大量のデータに対してループ内で1セルずつアクセスする場合、locilocよりもさらに高速なメソッドが存在します。

スカラー値への高速アクセス:at / iat

もし、単一の要素(スカラー値)のみを取得・更新したいのであれば、at(ラベルベース)やiat(位置ベース)を利用することを検討してください。

これらはlocilocが持つ「範囲選択機能」を削ぎ落としている分、アクセス速度が非常に高速です。

Python
# atによる高速アクセス
age_a = df.at['a', 'Age']

# iatによる高速アクセス
age_0 = df.iat[0, 1]

print(f"Age: {age_a}, {age_0}")
実行結果
Age: 26, 26

Callable(関数)による指定

locilocの引数には、ラムダ式などの関数を渡すことも可能です。

これはメソッドチェーンの中でデータを絞り込む際に非常に役立ちます。

Python
# メソッドチェーン内での利用例
filtered_df = (df.loc[lambda x: x['Age'] > 30]
               .iloc[:, 0:2])

print(filtered_df)
実行結果
      Name  Age
b      Bob   31
c  Charlie   35
d    David   40
e      Eve   45

注意すべき落とし穴

インデックスが整数の場合のloc

もっとも混乱を招くのは、インデックスが整数ラベルである場合です。

Python
df_int = pd.DataFrame({'val': [10, 20, 30]}, index=[1, 2, 3])

# これはラベル「1」を探す
print(df_int.loc[1]) 

# これは「1番目(0から数えて)」の要素を探す、つまりラベル「2」の行
print(df_int.iloc[1])

このように、インデックスが整数の場合、loc[1]が「1番目の行」ではなく「名前が1である行」を指すため、ilocの結果とズレが生じます。

意図しない挙動を防ぐためにも、位置で指定したいなら必ずilocを使うという習慣を徹底しましょう。

存在しないラベルの指定

locで存在しないラベルを指定すると KeyError が発生します。

一方、ilocで範囲外のインデックスを指定すると IndexError が発生します。

エラーメッセージから、どちらの指定方法で失敗したかを判断する手がかりになります。

まとめ

Pandasのlocilocは、データ抽出の基本でありながら、その違いが曖昧になりやすい要素です。

  • locは「名前(ラベル)」で指定し、スライスの終点を含む。
  • ilocは「番号(位置)」で指定し、スライスの終点を含まない。
  • 条件抽出にはlocが適しており、単一要素の高速アクセスにはatiatが有効。

2026年現在のデータ分析現場では、コードの堅牢性と可読性が重視されます。

「なんとなく動く」コードではなく、「なぜこちらを使うのか」を明確にして使い分けることで、バグの少ないクリーンな分析コードを記述できるようになります。

まずは、自分の扱っているデータのインデックスが「名前」なのか「単なる連番」なのかを確認することから始めてみてください。

適切な選択が、効率的なデータ操作への第一歩となります。

URLをコピーしました!