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を使うのが無難