Pandasのilocとixにおけるスライスの注意点

Pandasの行方向のスライスが思わぬ動きをした話し

import pandas as pd
import numpy as np
from IPython.display import display, HTML

numpyのスライスに代入->想像通り

fuga=np.zeros(5)
fuga[1:3]=1
fuga
array([ 0.,  1.,  1.,  0.,  0.])

ilocのスライスに代入->想像通り

fuga=np.zeros(5)
hoge=pd.DataFrame(fuga,columns=["test"])
hoge.iloc[1:3,0]=1
hoge
test
0 0.0
1 1.0
2 1.0
3 0.0
4 0.0

ixのスライスに代入->????

fuga=np.zeros(5)
hoge=pd.DataFrame(fuga,columns=["test"])
hoge.ix[1:3,0]=1
hoge
test
0 0.0
1 1.0
2 1.0
3 1.0
4 0.0

原因

pandas.DataFrame.ix

However, when an axis is integer based, ONLY label based access and not positional access is supported.
Thus, in such cases, it’s usually better to be explicit and use .iloc or .loc.

  • Indexが整数のみの場合はラベルアクセスのみになるから注意。

検証

ラベルアクセスすると同じになる

fuga=np.zeros(5)
hoge=pd.DataFrame(fuga,columns=["test"])
hoge.loc[1:3,"test"]=1
hoge
test
0 0.0
1 1.0
2 1.0
3 1.0
4 0.0

IndexをStrにすれば整数アクセス可能

fuga=np.zeros(5)
hoge=pd.DataFrame(fuga,columns=["test"])
hoge.index=[str(i) for i in hoge.index]
hoge.ix[1:3,"test"]=1
hoge
test
0 0.0
1 1.0
2 1.0
3 0.0
4 0.0

結論

  • ixを使った行のスライスは型に気をつける
  • 行スライスの代入はilocを使うのが無難