Python Tech

pandas.DataFrameの行をインデックス指定で取得するときの方法とエラー対処

pandas.DataFrameでは行・列の値を柔軟な方法で取り出すことができます。

ですが柔軟性があることは難易度の高さにも繋がります。

実際、DataFrameから任意の位置にある値を取り出す方法はいくつもあり、それぞれ少しずつ仕様が異なっていたりします。

この記事では、特に「行」の取り出しに「インデックス名または行番号」を指定してアクセスする方法とそのエラー対処について整理しています。

 

ValueError: -1 is not in range エラーの原因と対策

以下のようなエラーがでたとき

ValueError: -1 is not in range
KeyError: -1

任意の行を取り出したいなら、行の指定方法が誤っているようです。

例えば、以下のようにしても行は取り出せません。

last_item = df[-1] # 取り出せない

行番号を指定して任意の行を取得するには ilocを使用します。

row = df.iloc[行番号]

例えば、最終行を取り出すなら以下のようにします。

これで最後の行のSeriesを取得できます。

last_item = df.iloc[-1]

最終行を取り出すならスライスではなくilocを使うようにしましょう。

 

インデックス(行名)または行番号でアクセスする方法まとめ

pandas DataFrameの行の取り出し方にはいろいろな方法があり、初心者ほど混乱する部分があります。ついでにここで行の取り出し方について整理しておきましょう。

今回の記事では、indexや行の位置を指定することで行を取り出す方法を整理します。

任意の「列」の値を指定して行を検索するやり方はまた別の方法になるので、注意が必要です。

確認環境:Python 3.9, Pandas 1.2.3

サンプルデータとして以下のDataFrameを用意しておきます。

dic_data = {
    'id': ['A1', 'B1', 'C1'],
    'name': ['Alpha', 'Beta', 'Charlie'],
}
df = pd.DataFrame(dic_data)
df.set_index('id', inplace=True)

#        name
# id         
# A1    Alpha
# B1     Beta
# C1  Charlie

 

[]スライスで指定する方法

カッコ内に行番号またはインデックス名のスライスを指定する方法です。

必ずスライス [start:stop] のかたちで書きます。単独の数値([1]や[2])では指定できません。

どちらも戻り値はpandas.DataFrameです。

# スライスで行番号を指定した抽出方法
df_flag = df[1:3]  # 行番号で1〜2の行を取得。3は含まれないことに注意
print(df_flag)

#        name
# id         
# B1     Beta
# C1  Charlie
# スライスで行名を指定した抽出方法
df_flag = df['B1':'C1'] # 行名B1〜C1の行を取得。この場合は'C1'も含まれる
print(df_flag)

#        name
# id         
# B1     Beta
# C1  Charlie

 

細かいところを確認しておきましょう。

上の書き方だと、行番号で指定してもインデックス名で指定しても同じ結果となりました。

ただし行番号の方では[1:3]としていて、存在しない4番目の要素をレンジの後ろに指定していますね。これは、後ろ(stop)で指定した番号の一つ前までを取り出す仕様だからです。
(list型などでスライスを作るときと同様です)

一方、インデックス名(行名)のスライス指定では、レンジの後ろ(stop)で指定した要素も含まれることになります。この違いは慣れるまでややこしいですよね。

理解しやすいコードを書くなら、後で説明するiloc, locを使用したほうがよいでしょう。

 

取得する範囲
df[start:stop]

startからstop – 1

df[‘start_name’:’stop_name’]

‘start_name’から’stop_name’

※stop_nameも含む

 

ちなみにindexのスライス指定は、int型の整数だけでなく、文字列や日時(datetime型)など様々なtypeに対応しています。

例えば、indexが日付のとき(datetimeIndex)のときは、以下のような感じで日付範囲を指定してスライスを取り出せます。

since = datetime.date(2021, 1, 1)
until = datetime.date(2021, 1, 2)
df_flag = df_date[since:until]

doc(英語)

 

loc, ilocで指定する方法

こちらも行名、または行番号で特定の行を取得する方法です。

loc、ilocはあらゆる範囲のデータを柔軟に取り出すための仕組みです。

locでは、行名・列名を指定して、特定の位置の任意のデータを抽出できます。

val = df.loc['A1', 'name']
print(val)
# Alpha

ilocは行番号・列番号を指定して、同じように特定の位置の値を取り出します。

val = df.iloc[0, 0]
print(val)
# Alpha

行を取り出すには、列を指定しないだけでOKです。

locは行名を指定、ilocは行番号を指定することで、行を取り出します。

row = df.loc['A1']
row = df.iloc[0]
print(row)
# name    Alpha
# Name: A1, dtype: object

取り出されるのが1行だけなので、この場合は Seriesが返ってきます。

また、loc、ilocでもスライスで行を指定できます。

df_flag = df.loc['B1':'C1']
print(df_flag)

#        name
# id         
# B1     Beta
# C1  Charlie
df_flag = df.iloc[1:3]
print(df_flag)

#       name
# id         
# B1     Beta
# C1  Charlie

 

Pythonのスキルを使って毎月の収入源を増やすのが最適なんじゃないかという件

実際、今のスキルに合わせて仕事を獲得し、スキマ時間で毎月+5、+20、+70万円くらいの人が多いです。

必要なスキル、仕事の獲得までの流れは以下の記事で徹底解説しています。
もちろん全部無料です
空いた時間にぜひ参考にしてみてください。

 

まとめ

PandasフレームワークのDataFrameで特定の行を行番号・またはインデックス名を指定して取得する方法を整理しました。

  • この記事を書いた人

次世代ペンギン

長いのでペンギンとお呼びください。システム開発・プログラミングのお仕事をしています。甘味とコーヒーは生命線。多くの人に役立つ情報のシェアが目標です。

人気の記事

1

会社員でプログラマーとして働いている人、インフラやネットワークのエンジニアとして働いている人の中には、フリーランスのプログラマーとして独立、もしくは転向したい人もいるので ...

2

キャリアアップのため、または高収入を目指して、しっかりプログラミングを学びたいという人が増えてきましたね。 この記事では現役のエンジニアである私が、実際に仕事で稼げるよう ...

3

フリーランスのプログラマーにとって収入の向上に最も直結するのはスキルです。 必要なスキル、スキルの獲得方法が気になる人も多いでしょう。 また、これからフリーランスを目指す ...

4

Vuetifyの v-progress-circular コンポーネントは、数値データや処理状況を環状(円状)のデザインで教えてくれるUIデザインです。 ローディングのス ...

5

Vuexのstore(ストア)を使うと、各コンポーネント間で個別にデータのやり取りすることなく、データを一元的に管理できます。Vueでは欠かせない機能といえるでしょう。 ...

-Python, Tech
-, ,