11
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Passing list-likes to .loc or [] with any missing label will raise KeyError in the future

Last updated at Posted at 2019-06-28

はじめに

pandas を使っていたら、以下の警告(warning)が出て、将来的に(pandas 0.21.0以降で)はエラーになるよ、と書いてあるのでドキュメントをちゃんと読んでみた。

See the documentation here:
http://pandas.pydata.org/pandas-docs/stable/indexing.html#deprecate-loc-reindex-listlike
...
Passing list-likes to .loc or [] with any missing label will raise KeyError in the future, you can use .reindex() as an alternative.

該当箇所

# n_train はただの整数型の数値
# train_vars は df_train から必要な変数だけをとってくるために指定した文字列配列
X_train = df_train.loc[0:n_train, train_vars]

原因

ドキュメントから該当箇所を抜き出してみる。

In prior versions, using .loc[list-of-labels] would work as long as at least 1 of the keys was found (otherwise it would raise a KeyError). This behavior is deprecated and will show a warning message pointing to this section. The recommended alternative is to use .reindex().

【拙訳】
過去のバージョンでは、.loc[ラベルのリスト] は少なくとも 1つのキーが見つかる限りは正しく動作していた(1つも見つからなければ KeyError となった)。この振る舞いは非推奨となり、(ドキュメントの)このセクションを示す警告を表示する。代わりに推奨されるのは、.reindex()を使用することである。

つまり、

# こういうデータフレームに対して、
>>> df = pd.DataFrame({'a': [1,2,3], 'b': [4,5,6], 'c': [7,8,9]})
>>> df
   a  b  c
0  1  4  7
1  2  5  8
2  3  6  9

# これは OK で、
>>> df.loc[:,['a']]
   a
0  1
1  2
2  3

# これはダメ
>>> df.loc[:,['a','d']]
__main__:1: FutureWarning:
Passing list-likes to .loc or [] with any missing label will raise
KeyError in the future, you can use .reindex() as an alternative.

See the documentation here:
http://pandas.pydata.org/pandas-docs/stable/indexing.html#deprecate-loc-reindex-listlike
/Users/chase0213/.pyenv/versions/3.6.2/lib/python3.6/site-packages/pandas/core/indexing.py:1367: FutureWarning:
Passing list-likes to .loc or [] with any missing label will raise
KeyError in the future, you can use .reindex() as an alternative.

See the documentation here:
http://pandas.pydata.org/pandas-docs/stable/indexing.html#deprecate-loc-reindex-listlike
  return self._getitem_tuple(key)
   a   d
0  1 NaN
1  2 NaN
2  3 NaN

ということ。存在しないキーに対して参照すると、過去のバージョンでは何もなかったかのように Nan を突っ込んで返していたところ、ちゃんとエラーになるようにしたよ、というもの。
何も出なかったら見逃して処理続けちゃうよね、良い変更だね!

というわけで、対応策を考える。

対応策

1. ちゃんと存在するキーを指定する

前述の通り、ちゃんと存在するキーを指定すれば問題ない。
ただし、データを結合したりして、どうしてもキーのない行、列を使いたいときはあるので、その際には次の reindex() を使う。

2. reindex()を使う

# 新しく 'd' というキーを追加する
>>> labels = ['a','b','c','d']

# axis=1 に対して、labels を新しくキーに設定する
>>> df.reindex(labels, axis=1)
   a  b  c   d
0  1  4  7 NaN
1  2  5  8 NaN
2  3  6  9 NaN

# 何もエラーがでなくなる
>>> df.loc[:, ['a','d']]
   a   d
0  1 NaN
1  2 NaN
2  3 NaN

結論

deprecated になる箇所にはちゃんと意味があるので、警告だからといって無視せずにちゃんと理解して使おう(自戒)。

11
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?