pandas.DataFrameの行番号、列番号を取得

pandas.DataFrameの行名、列名から行番号、列番号を取得したり、列の要素の値から行名、行番号を取得したりする方法を説明します。 以下のpandas.DataFrameを例とします。

import pandas as pd

df = pd.read_csv('data/src/sample_pandas_normal.csv', index_col=0)

print(df)
#          age state  point
# name                     
# Alice     24    NY     64
# Bob       42    CA     92
# Charlie   18    CA     70
# Dave      68    TX     70
# Ellen     24    CA     88
# Frank     30    NY     57

サンプルのCSVファイルはこちら。

sample_pandas_normal.csv

以下の内容について説明します。

行名、列名から行番号、列番号を取得 get_loc()メソッド 行名、列名が重複している場合

index, columnsをリスト化

列の要素の値から行名、行番号を取得

行番号、列番号から行、列や要素の値を取得したい場合は以下の記事を参照。

行名、列名から行番号、列番号を取得

get_loc()メソッド

pandas.DataFrameのindex, columnsにはget_loc()というメソッドがあります。

pandas.Index.get_loc — pandas 0.23.1 documentation

行名または列名を引数に指定するとその行番号、列番号が返される。行番号、列番号ともに0始まりの整数。 行番号はindexから取得。

print(df.index.get_loc('Alice'))
# 0

print(df.index.get_loc('Ellen'))
# 4

列番号はcolumnsから取得。

print(df.columns.get_loc('age'))
# 0

print(df.columns.get_loc('point'))
# 2

いずれの場合も存在しない名前に対してはエラーKeyErrorとなります。

# print(df.index.get_loc('XXX'))
# KeyError: 'XXX'

# print(df.columns.get_loc('XXX'))
# KeyError: 'XXX'

行名、列名が重複している場合

行名、列名が重複している場合は注意が必要。以下、行名が重複している場合を例とするが、列名の場合も同じ。 rename()メソッドで行名を変更し、重複した行名を準備。

df_dup = df.rename(index={'Charlie': 'Bob'})
print(df_dup)
#        age state  point
# name                   
# Alice   24    NY     64
# Bob     42    CA     92
# Bob     18    CA     70
# Dave    68    TX     70
# Ellen   24    CA     88
# Frank   30    NY     57

この場合、get_loc()メソッドは行番号ではなくslice型オブジェクトを返す。

print(df_dup.index.get_loc('Bob'))
# slice(1, 3, None)

print(type(df_dup.index.get_loc('Bob')))
# <class 'slice'>

さらに重複した行名を増やす。

df_dup.rename(index={'Ellen': 'Bob'}, inplace=True)
print(df_dup)
#        age state  point
# name                   
# Alice   24    NY     64
# Bob     42    CA     92
# Bob     18    CA     70
# Dave    68    TX     70
# Bob     24    CA     88
# Frank   30    NY     57

スライスで表せない場合はbool型のNumPy配列numpy.ndarrayとなります。

print(df_dup.index.get_loc('Bob'))
# [False  True  True False  True False]

print(type(df_dup.index.get_loc('Bob')))
# <class 'numpy.ndarray'>

スライスオブジェクトもbool型の配列もインデックス参照やilocの位置指定に使用できます。bool型配列はlocでも使用可能。

print(df_dup[df_dup.index.get_loc('Bob')])
#       age state  point
# name                  
# Bob    42    CA     92
# Bob    18    CA     70
# Bob    24    CA     88

print(df_dup.iloc[df_dup.index.get_loc('Bob'), 0])
# name
# Bob    42
# Bob    18
# Bob    24
# Name: age, dtype: int64

なお、indexに対してはわざわざget_loc()でスライスオブジェクトやbool型配列を取得しなくてもquery()メソッドで要素を抽出できます。

print(df_dup.query('index == "Bob"'))
#       age state  point
# name                  
# Bob    42    CA     92
# Bob    18    CA     70
# Bob    24    CA     88

行名、列名が重複している場合でもスライスオブジェクトやbool型配列ではなく行番号、列番号を取得したい場合は次に説明するようにindex, columnsをリスト化します。

index, columnsをリスト化

index, columnsはlist()によってPython標準のリスト(list型オブジェクト)に変換できます。

l_index = list(df.index)
print(l_index)
# ['Alice', 'Bob', 'Charlie', 'Dave', 'Ellen', 'Frank']

print(type(l_index))
# <class 'list'>

l_columns = list(df.columns)
print(l_columns)
# ['age', 'state', 'point']

print(type(l_columns))
# <class 'list'>

リストのindex()メソッドでインデックス(何番目の要素か)を取得可能。

print(l_index.index('Bob'))
# 1

行名が重複している場合は組み込み関数enumerate()とリスト内包表記を利用することでインデックスのリストを取得できます。

l_index_dup = list(df_dup.index)
print(l_index_dup)
# ['Alice', 'Bob', 'Bob', 'Dave', 'Bob', 'Frank']

print([i for i, x in enumerate(l_index_dup) if x == 'Bob'])
# [1, 2, 4]

詳細は以下の記事を参照。

列の要素の値から行名、行番号を取得

行名、列名から行番号、列番号を取得するのではなく、任意の列の要素から対応する行名および行番号を取得する方法を示す。 引き続き以下のpandas.DataFrameを例とします。

print(df)
#          age state  point
# name                     
# Alice     24    NY     64
# Bob       42    CA     92
# Charlie   18    CA     70
# Dave      68    TX     70
# Ellen     24    CA     88
# Frank     30    NY     57

行名の取得 query()メソッドで任意の列の要素に対する条件で行を抽出できます。返り値はpandas.DataFrame。

print(df.query('state == "CA"'))
#          age state  point
# name                     
# Bob       42    CA     92
# Charlie   18    CA     70
# Ellen     24    CA     88

query()で抽出したpandas.DataFrameのindexをリスト化すると、特定の値の行名のリストが取得できます。

print(list(df.query('state == "CA"').index))
# ['Bob', 'Charlie', 'Ellen']

抽出されるのが1行の場合も同じ。リストではなく行名の値が欲しい場合はindexの最初の要素[0]を取得すれば問題ありません。

print(df.query('state == "TX"'))
#       age state  point
# name                  
# Dave   68    TX     70

print(list(df.query('state == "TX"').index))
# ['Dave']

print(df.query('state == "TX"').index[0])
# Dave

行番号の取得 行名ではなく行番号を取得したい場合は、reset_index()でindexを0始まりの連番にリセットしてから同様の処理を行う。

print(df.reset_index())
#       name  age state  point
# 0    Alice   24    NY     64
# 1      Bob   42    CA     92
# 2  Charlie   18    CA     70
# 3     Dave   68    TX     70
# 4    Ellen   24    CA     88
# 5    Frank   30    NY     57

print(list(df.reset_index().query('state == "CA"').index))
# [1, 2, 4]

print(list(df.reset_index().query('state == "TX"').index))
# [3]

print(df.reset_index().query('state == "TX"').index[0])
# 3

シェア

関連カテゴリー

Python pandas

pandasで分位数・パーセンタイルを取得するquantile pandas-datareaderで株価や人口のデータを取得 pandasのオプション設定を確認・変更する方法 pandasのcut, qcut関数でビニング処理(ビン分割) pandasでcsvファイルの書き出し・追記(to_csv) pandasで条件に応じて値を代入(where, mask) pandasで数値を丸める(四捨五入、偶数への丸め) pandas.DataFrameをGroupByでグルーピングし統計量を算出 pandasでExcelファイル(xlsx, xls)の書き込み(to_excel) Python, pandasでwebページの表(htmlのtable)をスクレイピング pandasでカテゴリ変数をダミー変数に変換(get_dummies) Python, pandas, seabornでペアプロット図(散布図行列)を作成 pandasで特定の条件を満たす要素数をカウント(全体、行・列ごと) PythonでRESAS APIを使ってデータをダウンロード pandasで複数条件のand, or, notから行を抽出(選択)

Last Updated: 6/26/2019, 10:34:03 PM