Pandasのlocとiloc:データの選択と抽出
Pandasライブラリにおける`loc`と`iloc`は、DataFrameやSeriesからデータを効率的に選択・抽出するための強力なメソッドです。これらは、ラベルベースの選択と整数位置ベースの選択という、異なるアプローチを提供します。これらのメソッドを理解し使いこなすことは、データ分析における必須スキルと言えます。
loc:ラベルベースの選択
`loc`は、DataFrameやSeriesのインデックスラベルや列ラベルを使用してデータを選択します。これは、データに意味のある名前が付いている場合に特に役立ちます。
行の選択
`loc`を使用して特定の行を選択するには、インデックスラベルを指定します。
“`python
import pandas as pd
data = {‘col1’: [1, 2, 3], ‘col2’: [4, 5, 6]}
df = pd.DataFrame(data, index=[‘a’, ‘b’, ‘c’])
# ラベル’a’の行を選択
print(df.loc[‘a’])
# ラベル’a’と’c’の行を選択
print(df.loc[[‘a’, ‘c’]])
“`
列の選択
`loc`を使用して特定の列を選択するには、列ラベルを指定します。
“`python
# ラベル’col1’の列を選択
print(df.loc[:, ‘col1’]) # ‘:’は全ての行を意味します
# ラベル’col1’と’col2’の列を選択
print(df.loc[:, [‘col1’, ‘col2’]])
“`
行と列の同時選択
`loc`では、行ラベルと列ラベルをカンマで区切って指定することで、特定の行と列を同時に選択できます。
“`python
# ラベル’a’の行とラベル’col1’の列を選択
print(df.loc[‘a’, ‘col1’])
# ラベル’a’と’b’の行、ラベル’col1’の列を選択
print(df.loc[[‘a’, ‘b’], ‘col1’])
# ラベル’a’の行、ラベル’col1’と’col2’の列を選択
print(df.loc[‘a’, [‘col1’, ‘col2’]])
# ラベル’a’と’b’の行、ラベル’col1’と’col2’の列を選択
print(df.loc[[‘a’, ‘b’], [‘col1’, ‘col2’]])
“`
スライシング
`loc`はスライシングにも対応しており、インデックスラベルの範囲を指定してデータを取得できます。
“`python
# ラベル’a’から’b’までの行を選択 (bも含む)
print(df.loc[‘a’:’b’])
# ラベル’col1’から’col2’までの列を選択 (col2も含む)
print(df.loc[:, ‘col1′:’col2’])
# ラベル’a’から’b’までの行と、ラベル’col1’から’col2’までの列を選択
print(df.loc[‘a’:’b’, ‘col1′:’col2’])
“`
条件による選択
`loc`は、ブールインデックスを使用して条件に合致する行を選択することも可能です。
“`python
data_cond = {‘col1’: [10, 20, 30], ‘col2’: [40, 50, 60]}
df_cond = pd.DataFrame(data_cond, index=[‘x’, ‘y’, ‘z’])
# ‘col1’が20より大きい行を選択
print(df_cond.loc[df_cond[‘col1’] > 20])
# 複数の条件を組み合わせた選択 (AND条件)
print(df_cond.loc[(df_cond[‘col1’] > 10) & (df_cond[‘col2’] < 50)])
# 複数の条件を組み合わせた選択 (OR条件)
print(df_cond.loc[(df_cond['col1'] 50)])
“`
iloc:整数位置ベースの選択
`iloc`は、整数位置(0から始まるインデックス)を使用してデータを選択します。これは、データの順序が重要である場合や、ラベルに依存しない操作を行いたい場合に便利です。
行の選択
`iloc`を使用して特定の行を選択するには、その行の整数位置を指定します。
“`python
# 0番目の行を選択
print(df.iloc[0])
# 0番目と2番目の行を選択
print(df.iloc[[0, 2]])
“`
列の選択
`iloc`を使用して特定の列を選択するには、その列の整数位置を指定します。
“`python
# 0番目の列を選択
print(df.iloc[:, 0]) # ‘:’は全ての行を意味します
# 0番目と1番目の列を選択
print(df.iloc[:, [0, 1]])
“`
行と列の同時選択
`iloc`では、行の整数位置と列の整数位置をカンマで区切って指定することで、特定の行と列を同時に選択できます。
“`python
# 0番目の行と0番目の列を選択
print(df.iloc[0, 0])
# 0番目と1番目の行、0番目の列を選択
print(df.iloc[[0, 1], 0])
# 0番目の行、0番目と1番目の列を選択
print(df.iloc[0, [0, 1]])
# 0番目と1番目の行、0番目と1番目の列を選択
print(df.iloc[[0, 1], [0, 1]])
“`
スライシング
`iloc`はスライシングにも対応しており、整数位置の範囲を指定してデータを取得できます。`iloc`のスライシングは、Pythonのリストスライシングと同様に、終了位置は含まれないことに注意が必要です。
“`python
# 0番目から2番目までの行を選択 (2番目の行は含まない)
print(df.iloc[0:2])
# 0番目から2番目までの列を選択 (2番目の列は含まない)
print(df.iloc[:, 0:2])
# 0番目から2番目までの行と、0番目から2番目までの列を選択
print(df.iloc[0:2, 0:2])
“`
負のインデックス
`iloc`では、負のインデックスを使用して末尾からの要素を指定することも可能です。
“`python
# 最後の行を選択
print(df.iloc[-1])
# 最後の2行を選択
print(df.iloc[-2:])
# 最後の列を選択
print(df.iloc[:, -1])
“`
locとilocの使い分け
* **`loc`**:インデックスラベルや列ラベルが明確で、それらに基づいてデータを操作したい場合に最適です。データの意味を理解している場合には、コードの可読性が向上します。
* **`iloc`**:データの物理的な位置に基づいてデータを操作したい場合、またはデータにラベルがない場合に便利です。特に、数値計算や位置に基づいたデータ処理で威力を発揮します。
注意点と応用
* **データ型の混在**: DataFrameのインデックスや列に異なるデータ型が混在している場合、`loc`での操作は直感的でないことがあります。`iloc`は常に整数位置で動作するため、このような場合でも安定した操作が可能です。
* **ビューとコピー**: `loc`や`iloc`でデータを選択した場合、それが元のDataFrameのビュー(参照)であるか、コピーであるかは、状況によって異なります。ビューの場合、選択したデータへの変更は元のDataFrameにも反映されますが、コピーの場合は独立したデータとなります。意図しない変更を防ぐためには、`.copy()`メソッドを使用して明示的にコピーを作成することが推奨される場合があります。
* **パフォーマンス**: 大規模なデータセットの場合、`loc`と`iloc`のパフォーマンスは、選択方法(単一要素、リスト、スライス、ブールインデックス)によって影響を受けることがあります。
まとめ
`loc`と`iloc`はPandasでデータを操作する上で不可欠なメソッドです。`loc`はラベルベース、`iloc`は整数位置ベースという明確な違いを理解し、それぞれの特性を活かすことで、データ分析の効率と正確性を大幅に向上させることができます。これらのメソッドを使いこなすことは、Pandasを用いたデータサイエンスの基礎となります。
