「pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_value()」のエラーについて、発生原因と回避方法をメモしておきます。

エラーメッセージが出るコード
| length | global_point | |
|---|---|---|
| 1 | 19088 | 1469 |
| 1 | 19088 | 1469 |
| 2 | 13077 | 34 |
| 3 | 238673 | 2 |
| 4 | 54083 | 129 |
| 5 | 16013 | 8 |
| 6 | 1647 | 8 |
| 7 | 46998 | 6 |
| 8 | 4458 | 14 |
| 9 | 7235 | 80 |
| 10 | 707667 | 2025 |
上記の様な表をpandasで読み込み、下記のように
df2 = df[df["length"]>=10000]
で条件抽出したあと更に、抽出後のデータフレームの数に基づくfor文を使おうとすると下記の様なエラーが出ます。
import pandas as pd df = pd.read_excel("sample.xlsx") df2 = df[df["length"]>=10000] for i in range(len(df2)): length=df2["global_point"][i] print(length)
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-13-304502578a15> in <module>
6
7 for i in range(len(df2)):
----> 8 length=df2["global_point"][i]
9 print(length)
c:\python37\lib\site-packages\pandas\core\series.py in __getitem__(self, key)
1069 key = com.apply_if_callable(key, self)
1070 try:
-> 1071 result = self.index.get_value(self, key)
1072
1073 if not is_scalar(result):
c:\python37\lib\site-packages\pandas\core\indexes\base.py in get_value(self, series, key)
4728 k = self._convert_scalar_indexer(k, kind="getitem")
4729 try:
-> 4730 return self._engine.get_value(s, k, tz=getattr(series.dtype, "tz", None))
4731 except KeyError as e1:
4732 if len(self) > 0 and (self.holds_integer() or self.is_boolean()):
pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_value()
pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_value()
pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()
pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.Int64HashTable.get_item()
pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.Int64HashTable.get_item()
KeyError: 5
原因:エラーの理由はインデックスが連番になっていないから
発生原因は至極単純で、条件抽出したあとのデータフレームはインデックスがバラバラな状態となっているからです。
なのでこの状態でfor分のrange()の様な方法を使うと、該当するインデックスが無い行を参照しようとしていまうためエラーが出て落ちます。

対処方法:『.reset_index(drop=True)』でインデックスを振り直す
このエラーを回避するもっともシンプルな方法は『reset_index(drop=True)』をデータフレームに適用してインデックスを振り直すことです。
条件抽出したあとのデータフレームに下記コードで処理することでインデックスの振り直しが行われ、インデックスが0からの連番になります。
df2 = df2.reset_index(drop=True)

エラーが出ないコード
import pandas as pd df = pd.read_excel("sample.xlsx") df2 = df[df["length"]>=10000] df2 = df2.reset_index(drop=True) for i in range(len(df2)): length=df2["global_point"][i] print(length)