pandas

pandasでixを使うのはもうやめよう

はじめに

pandasのDataFrameにはixというメソッドがあります。
が、これは今はもう非推奨です。

非推奨な理由はリンク先の本家ドキュメントに書いてありますが適当に訳すと、
「ixはユーザーがほしいものを推測し、魔法を提供してきた。インデックスのデータ型により、位置的なインデックスとしても、ラベルでのインデックスとしても動作した。しかしこれは長年ユーザーに混乱をもたらした」

Qiitaにも「非推奨だしix使うのやめよう」という記事は見かけましたが実際どういう困ったことが起きたという記事は見かけなかったので、以後、私の体験談です。

実際に困る状況

こんな感じのcsvを読み込ませたとします。

sample.csv
No,data1,data2
1,12,34
2,23,45
3,34,56
4,45,67
5,56,78
6,67,89
7,78,90
8,89,12

3行目(位置インデックス2)から3行分取り出すぜ、と以下のように書きます。

>>> import pandas as pd
>>> df = pd.read_csv('sample.csv')
>>> df.ix[2:5]
   No  data1  data2
2   3     34     56
3   4     45     67
4   5     56     78
5   6     67     89

あれ?

起きていることの整理

今回の場合、インデックスの型は整数です。このとき、ixメソッドは2:5とスライスを渡されると「インデックスの値が2から5まで」を返しているようです。しかしPythonプログラマなら「2から4まで」が返されると期待するでしょう。1

代替方法

本家ドキュメントに書いてありますが位置インデックスで取りたいのかラベルインデックスで取りたいのかによってilocもしくはlocメソッドを使いましょう。

ilocを使えば意図しない「インデックスの値が5の行」は含まれなくなります。

ilocを使って位置インデックスで取る
>>> df.iloc[2:5]
   No  data1  data2
2   3     34     56
3   4     45     67
4   5     56     78

本当に「インデックスの値が2から5まで」取りたいという場合も明示的にlocを使いましょう。

locを使ってラベルインデックスで取る
>>> df.loc[2:5]
   No  data1  data2
2   3     34     56
3   4     45     67
4   5     56     78
5   6     67     89

  1. まあこのスライスで指定したもの-1までという動作も毎回微妙には感じていますが