Pandasを利用してデータ分析を行う際、多くの場合は列名(ラベル)を指定してデータにアクセスします。
しかし、特定のライブラリとの連携や、特定の列の隣に新しい列を挿入したい場合など、「列名が左から何番目にあるか(インデックス番号)」を知りたい場面が多々あります。
PandasのDataFrameにおいて、列名は Index オブジェクトとして管理されており、これには位置情報を取得するための効率的なメソッドが用意されています。
本記事では、単一のインデックスを取得する get_loc や、複数のインデックスを効率的に取得する get_indexer の使い方、さらには実務で直面しやすい重複列名の扱いについて詳しく解説します。
get_locメソッドを用いた基本的なインデックス取得方法
PandasのDataFrameで特定の列が何番目にあるかを調べる最も標準的な方法は、df.columns.get_loc() メソッドを使用することです。
このメソッドは、指定したラベルの 整数値による位置(0からの連番) を返します。
get_locの基本的な構文と使い方
まずは、もっともシンプルな例から見ていきましょう。
以下のコードでは、サンプルデータを作成し、特定の列名のインデックス番号を取得しています。
import pandas as pd
# サンプルデータの作成
df = pd.DataFrame({
'Name': ['Alice', 'Bob', 'Charlie'],
'Age': [25, 30, 35],
'City': ['Tokyo', 'Osaka', 'Nagoya'],
'Score': [85, 90, 95]
})
# 'City' 列のインデックス番号を取得
city_idx = df.columns.get_loc('City')
print(f"City列のインデックス: {city_idx}")
City列のインデックス: 2
この例では、'Name' が0、'Age' が1、'City' が2となるため、結果として 2 が返されます。
非常に直感的で分かりやすい挙動です。
存在しない列名を指定した場合の挙動
get_loc を使用する際に注意が必要なのは、存在しない列名を指定すると例外が発生する という点です。
try:
# 存在しない列名を指定
idx = df.columns.get_loc('Salary')
except KeyError as e:
print(f"エラーが発生しました: {e}")
エラーが発生しました: 'Salary'
このように、指定した列名が見つからない場合は KeyError が送出されます。
プログラムの中で動的に列名を扱う場合は、あらかじめ列名が存在するかを確認するか、try-except 文でハンドリングを行うのが安全です。
get_indexerメソッドによる複数列の一括取得
単一の列ではなく、複数の列名を一括してインデックス番号に変換したい場合 は、get_indexer メソッドが非常に便利です。
複数列をリストで指定するメリット
get_loc は一度に1つのラベルしか処理できませんが、get_indexer はリスト形式で複数のラベルを受け取り、対応するインデックスの配列(numpy.ndarray)を返します。
# 複数の列名をリストで指定
target_cols = ['Score', 'Name', 'Age']
indices = df.columns.get_indexer(target_cols)
print(f"指定した列のインデックス一覧: {indices}")
指定した列のインデックス一覧: [3 0 1]
get_indexer の優れた点は、「存在しない列名」が含まれていてもエラーにならず、代わりに -1 を返す という挙動にあります。
これにより、リストの中に不確実な列名が含まれている場合でも処理を中断せずに進めることが可能です。
欠損している列名の扱い
データクレンジングなどの現場では、指定した列が必ずしもすべてのデータセットに含まれているとは限りません。
その場合に get_indexer がどのように機能するかを確認しましょう。
# 一部の列名が存在しない場合
target_cols = ['Name', 'Unknown', 'City']
indices = df.columns.get_indexer(target_cols)
print(f"インデックスの取得結果: {indices}")
インデックスの取得結果: [ 0 -1 2]
出力結果の -1 は、そのラベルがIndexオブジェクト内に存在しなかったことを示しています。
この仕組みを利用すれば、indices >= 0 のような条件式で、実際に存在する列だけを抽出する といったフィルタリングも容易に行えます。
重複した列名がある場合の挙動と注意点
Pandasでは、技術的には同じ名前の列を複数持つことが可能です。
しかし、列名が重複している場合、get_loc の挙動は通常時と異なります。
重複がある場合のget_locの戻り値
通常、get_loc は整数(int)を返しますが、列名が重複している場合は整数ではなくスライスや真偽値の配列(mask)を返す ことがあります。
# 重複した列名を持つDataFrameの作成
df_dup = pd.DataFrame(
[[1, 2, 3]],
columns=['A', 'B', 'A']
)
# 重複している 'A' 列のインデックスを取得
a_idx = df_dup.columns.get_loc('A')
print(f"重複がある場合の戻り値の型: {type(a_idx)}")
print(f"戻り値の内容: {a_idx}")
重複がある場合の戻り値の型: <class 'numpy.ndarray'>
戻り値の内容: [ True False True]
このように、戻り値が数値(int)であることを前提としたコードを書いていると、重複列名が含まれた瞬間にエラー(TypeErrorなど)の原因となります。
実務では、データソースの品質を考慮し、事前に df.columns.is_unique で一意性をチェックするか、重複を許容しない設計にすることが推奨されます。
実践的な活用シーン:列の挿入や特定位置の操作
列のインデックスを取得する主な目的の一つに、df.insert() メソッドを用いた「特定の位置への列挿入」があります。
特定の列の隣に新しい列を挿入する
デフォルトでは、新しい列をDataFrameに追加すると常に右端(最後尾)に配置されます。
しかし、get_loc で位置を特定すれば、任意の列の直前や直後に列を差し込む ことができます。
# 'Age' 列のインデックスを取得
age_idx = df.columns.get_loc('Age')
# 'Age' 列のすぐ右側(インデックス + 1)に 'Gender' 列を挿入
df.insert(age_idx + 1, 'Gender', ['F', 'M', 'M'])
print(df)
Name Age Gender City Score
0 Alice 25 F Tokyo 85
1 Bob 30 M Osaka 90
2 Charlie 35 M Nagoya 95
このように、df.insert(loc, column, value) の第一引数に取得したインデックスを渡すことで、データの並び順を制御できます。
レポート作成などで特定の項目を隣接させたい場合に、非常に重宝するテクニックです。
NumPyを用いた代替手法との比較
Pandasのメソッドを使わずに、Python標準のリスト機能やNumPyを用いてインデックスを取得することも可能です。
しかし、これらにはいくつかのデメリットがあります。
例えば、df.columns.tolist().index('City') という書き方もありますが、これは一度リストオブジェクトを生成するため、列数が多い場合にパフォーマンスが低下 します。
また、NumPyの np.where(df.columns == 'City') を使う方法もありますが、返り値がタプル形式になるなど、後続の処理で少し手間がかかることがあります。
Pandasの Index.get_loc や Index.get_indexer は、内部的にハッシュテーブルを利用して最適化されているため、数万件の列を持つような巨大なデータフレームでも高速に動作 するよう設計されています。
特別な理由がない限り、Pandas純正のメソッドを利用するのがベストプラクティスです。
まとめ
本記事では、Pandasで列名からインデックス番号を取得するさまざまな方法について解説しました。
重要なポイントを整理すると以下の通りです。
- 単一の列名 からインデックスを取得するには
df.columns.get_loc('列名')を使用する。 - 複数の列名 を一括で変換し、かつ存在しない列を柔軟に扱いたい場合は
df.columns.get_indexer(['列1', '列2'])が最適。 - 存在しない列名 を
get_locに渡すとKeyErrorになる。 - 重複した列名 がある場合、戻り値が整数ではなく配列やスライスになる可能性があるため注意が必要。
- 列の挿入位置を指定する
df.insert()と組み合わせることで、データの構造を柔軟に変更できる。
データ分析のパイプラインを構築する際、列の「名前」と「位置」を自由自在に変換できるスキルは、コードの可読性と堅牢性を高めるために欠かせません。
今回紹介したメソッドを使い分け、より効率的なデータ操作を実現してください。
さらに詳しい情報は、Pandas公式ドキュメントのIndexセクション を参照することをお勧めします。
