Pandas データ選択(loc / iloc / at)

データ選択は Pandas で最もよく使われる操作の一つです。loc、iloc、atの違いと適用シーンを理解することで、より効率的にデータを処理できます。


loc と iloc の違い

特徴 loc iloc
インデックス方式 ラベルインデックス(label-based) 位置インデックス(integer-based)
スライス 終了位置を含む 終了位置を含まない
単一の値 スカラーを返す スカラーを返す
推奨シーン 明確なインデックスラベルがある場合 位置で選択する場合

例

import pandas as pd

# サンプル DataFrame を作成
df = pd.DataFrame({
    "姓名": ["张三", "李四", "王五", "赵六", "钱七"],
    "年龄": [25, 30, 28, 35, 22],
    "城市": ["北京", "上海", "广州", "深圳", "杭州"]
}, index=[1, 3, 5, 7, 9])  # 注意:インデックスは連続していない

print("DataFrame:")
print(df)
print()

# loc: ラベルインデックスを使用(終了位置を含む)
print("df.loc[1:5](ラベルスライス、5を含む):")
print(df.loc[1:5])
print()

# iloc: 位置インデックスを使用(終了位置を含まない)
print("df.iloc[0:2](位置スライス、2を含まない):")
print(df.iloc[0:2])

loc の使い方

行の選択

例

import pandas as pd

df = pd.DataFrame({
    "姓名": ["张三", "李四", "王五", "赵六"],
    "年龄": [25, 30, 28, 35],
    "城市": ["北京", "上海", "广州", "深圳"]
}, index=["a", "b", "c", "d"])

# 単一行を選択(Series を返す)
print("1行を選択:")
print(df.loc["a"])
print()

# 複数行を選択
print("複数行を選択:")
print(df.loc[["a", "c"]])
print()

# スライス選択(開始と終了を含む)
print("スライス選択:")
print(df.loc["a":"c"])

列の選択

例

import pandas as pd

df = pd.DataFrame({
    "姓名": ["张三", "李四", "王五"],
    "年龄": [25, 30, 28],
    "城市": ["北京", "上海", "广州"]
}, index=["a", "b", "c"])

# 単一列を選択
print("単一列を選択:")
print(df.loc[:, "姓名"])
print()

# 複数列を選択
print("複数列を選択:")
print(df.loc[:, ["姓名", "城市"]])
print()

# スライスで列を選択
print("スライスで列を選択:")
print(df.loc[:, "姓名":"城市"])

特定の行・列の選択(推奨方法)

例

import pandas as pd

df = pd.DataFrame({
    "姓名": ["张三", "李四", "王五", "赵六"],
    "年龄": [25, 30, 28, 35],
    "城市": ["北京", "上海", "广州", "深圳"]
}, index=["a", "b", "c", "d"])

# 特定の行・列を選択
print("単一の値を選択:")
print(df.loc["a", "姓名"])  # "张三" を返す
print(type(df.loc["a", "姓名"]))  # 型は str
print()

# 複数行・複数列を選択
print("サブセットを選択:")
print(df.loc[["a", "c"], ["姓名", "城市"]])
print()

# 条件による選択
print("年齢が28より大きい行:")
print(df.loc[df["年龄"] > 28])

iloc の使い方

位置による選択

例

import pandas as pd

df = pd.DataFrame({
    "姓名": ["张三", "李四", "王五", "赵六"],
    "年龄": [25, 30, 28, 35],
    "城市": ["北京", "上海", "广州", "深圳"]
})

# 0行目を選択
print("0行目を選択:")
print(df.iloc[0])
print()

# 先頭3行を選択
print("先頭3行を選択:")
print(df.iloc[:3])
print()

# 特定の行を選択
print("特定の行を選択:")
print(df.iloc[[0, 2, 3]])
print()

# 負のインデックス(末尾から)
print("最後の1行を選択:")
print(df.iloc[-1])
print()

print("最後の3行を選択:")
print(df.iloc[-3:])

列の選択

例

import pandas as pd

df = pd.DataFrame({
    "姓名": ["张三", "李四", "王五"],
    "年龄": [25, 30, 28],
    "城市": ["北京", "上海", "广州"]
})

# 0列目を選択
print("0列目:")
print(df.iloc[:, 0])
print()

# 1列目と2列目を選択
print("複数列を選択:")
print(df.iloc[:, [1, 2]])
print()

# スライス選択
print("スライスで列を選択:")
print(df.iloc[:, 0:2])

at と iat(単一の値を取得)

atとiatは、単一の値の取得・設定に特化したアクセサで、locとiloc>更快。

例

import pandas as pd
import time
import numpy as np

# パフォーマンステスト用の大きな DataFrame を作成
df = pd.DataFrame(np.random.randn(1000, 10), columns=[f"col_{i}" for i in range(10)])

# at で単一の値を取得(ラベルインデックス)
print(f"at: {df.at[0, 'col_0']}")

# iat で単一の値を取得(位置インデックス)
print(f"iat: {df.iat[0, 0]}")

# パフォーマンス比較
n = 10000

start = time.time()
for _ in range(n):
    _ = df.iloc[0, 0]
print(f"iloc 所要時間: {time.time() - start:.4f}s")

start = time.time()
for _ in range(n):
    _ = df.iat[0, 0]
print(f"iat 所要時間: {time.time() - start:.4f}s")

条件による選択

ブール条件を使用したデータのフィルタリングは、最も一般的な操作の一つです。

例

import pandas as pd

df = pd.DataFrame({
    "姓名": ["张三", "李四", "王五", "赵六"],
    "年龄": [25, 30, 28, 35],
    "城市": ["北京", "上海", "广州", "北京"],
    "薪资": [12000, 15000, 11000, 18000]
})

# 単一条件
print("年齢が28より大きい従業員:")
print(df[df["年龄"] > 28])
print()

# 複数条件(& | ~ を使用)
print("北京かつ給与が12000より大きい:")
print(df[(df["城市"] == "北京") & (df["薪资"] > 12000)])
print()

# isin によるフィルタリング
print("都市が北京または上海:")
print(df[df["城市"].isin(["北京", "上海"])])
print()

# 文字列の部分一致
print("名前に'三'を含む:")
print(df[df["姓名"].str.contains("三")])

注意事項

1、スライスは終了位置を含む

locのスライスは終了位置を含み、ilocは含みません。

2、存在しないインデックスはエラーになる

使用loc時にインデックスが存在しないと KeyError が発生します。代わりにloc[index_list]を組み合わせて使用できますreindex。

3、優先して使用することを推奨loc

なぜならlocより読みやすく、エラーも発生しにくい。ただし、位置による選択が必要な場合は除く。

at/iat単一の値にアクセスする最も速い方法です。loc/iloc複数の値を選択するために使用します。適切な方法を選ぶことで、コードの性能と可読性を向上させることができます。

その他の拡張