pandas loc修改多索引的dataFrame?
pandas loc modifies dataFrame with multi index?
我发现了 loc 的一些有趣行为(错误?),具有多索引数据框,其中第一个索引是单个索引。使用 loc (第一次)后,第一个索引(多索引)消失了!
示例:
In [1]: import pandas as pd
In [2]: x = pd.DataFrame({'idx1':[1]*10, 'idx2':[1]*5+[2]*5, 'idx3':range(5)+range(5), 'data': [1]*10})
In [3]: x = x.set_index(['idx1', 'idx2', 'idx3']).sortlevel()
我的数据框:
In [4]: x
Out[4]:
data
idx1 idx2 idx3
1 1 0 1
1 1
2 1
3 1
4 1
2 0 1
1 1
2 1
3 1
4 1
loc第一次使用:
In [5]: x.loc[1,:,:]
Out[5]:
data
idx2 idx3
1 0 1
1 1
2 1
3 1
4 1
2 0 1
1 1
2 1
3 1
4 1
现在DataFrame只有两个索引:
In [6]: x
Out[6]:
data
idx2 idx3
1 0 1
1 1
2 1
3 1
4 1
2 0 1
1 1
2 1
3 1
4 1
当 'idx1' 有多个值时不会发生这种情况:
In [7]: x = pd.DataFrame({'idx1':[1]*3+[2]*7, 'idx2':[1]*5+[2]*5, 'idx3':range(5)+range(5), 'data': [1]*10})
In [8]: x = x.set_index(['idx1', 'idx2', 'idx3']).sortlevel()
In [9]: x
Out[9]:
data
idx1 idx2 idx3
1 1 0 1
1 1
2 1
2 1 3 1
4 1
2 0 1
1 1
2 1
3 1
4 1
In [10]: x.loc[1,:,:]
Out[10]:
data
idx1 idx2 idx3
1 1 0 1
1 1
2 1
In [11]: x
Out[11]:
data
idx1 idx2 idx3
1 1 0 1
1 1
2 1
2 1 3 1
4 1
2 0 1
1 1
2 1
3 1
4 1
这是正常现象吗?如何避免这种情况?
python 2.7 32 位,pandas==0.16.2,numpy==1.11.1+mkl
我认为更好的是 select 和 slicers
,它 return 相同的输出 - 所有级别:
x = pd.DataFrame({'idx1':[1]*10, 'idx2':[1]*5+[2]*5, 'idx3':list(range(5))+list(range(5)), 'data': [1]*10})
x = x.set_index(['idx1', 'idx2', 'idx3']).sortlevel()
print (x)
data
idx1 idx2 idx3
1 1 0 1
1 1
2 1
3 1
4 1
2 0 1
1 1
2 1
3 1
4 1
idx = pd.IndexSlice
print (x.loc[idx[1,:,:],:])
data
idx1 idx2 idx3
1 1 0 1
1 1
2 1
3 1
4 1
2 0 1
1 1
2 1
3 1
4 1
如果需要删除级别,请使用 xs
和参数 drop_level
:
print (x.xs(1, level=0, drop_level=True))
data
idx2 idx3
1 0 1
1 1
2 1
3 1
4 1
2 0 1
1 1
2 1
3 1
4 1
print (x.xs(1, level=0, drop_level=False))
data
idx1 idx2 idx3
1 1 0 1
1 1
2 1
3 1
4 1
2 0 1
1 1
2 1
3 1
4 1
第二个样本:
x = pd.DataFrame({'idx1':[1]*3+[2]*7, 'idx2':[1]*5+[2]*5, 'idx3':list(range(5))+list(range(5)), 'data': [1]*10})
x = x.set_index(['idx1', 'idx2', 'idx3']).sortlevel()
print (x)
data
idx1 idx2 idx3
1 1 0 1
1 1
2 1
2 1 3 1
4 1
2 0 1
1 1
2 1
3 1
4 1
idx = pd.IndexSlice
print (x.loc[idx[1,:,:],:])
data
idx1 idx2 idx3
1 1 0 1
1 1
2 1
print (x.xs(1, level=0, drop_level=True))
data
idx2 idx3
1 0 1
1 1
2 1
print (x.xs(1, level=0, drop_level=False))
data
idx1 idx2 idx3
1 1 0 1
1 1
2 1
我发现了 loc 的一些有趣行为(错误?),具有多索引数据框,其中第一个索引是单个索引。使用 loc (第一次)后,第一个索引(多索引)消失了!
示例:
In [1]: import pandas as pd
In [2]: x = pd.DataFrame({'idx1':[1]*10, 'idx2':[1]*5+[2]*5, 'idx3':range(5)+range(5), 'data': [1]*10})
In [3]: x = x.set_index(['idx1', 'idx2', 'idx3']).sortlevel()
我的数据框:
In [4]: x
Out[4]:
data
idx1 idx2 idx3
1 1 0 1
1 1
2 1
3 1
4 1
2 0 1
1 1
2 1
3 1
4 1
loc第一次使用:
In [5]: x.loc[1,:,:]
Out[5]:
data
idx2 idx3
1 0 1
1 1
2 1
3 1
4 1
2 0 1
1 1
2 1
3 1
4 1
现在DataFrame只有两个索引:
In [6]: x
Out[6]:
data
idx2 idx3
1 0 1
1 1
2 1
3 1
4 1
2 0 1
1 1
2 1
3 1
4 1
当 'idx1' 有多个值时不会发生这种情况:
In [7]: x = pd.DataFrame({'idx1':[1]*3+[2]*7, 'idx2':[1]*5+[2]*5, 'idx3':range(5)+range(5), 'data': [1]*10})
In [8]: x = x.set_index(['idx1', 'idx2', 'idx3']).sortlevel()
In [9]: x
Out[9]:
data
idx1 idx2 idx3
1 1 0 1
1 1
2 1
2 1 3 1
4 1
2 0 1
1 1
2 1
3 1
4 1
In [10]: x.loc[1,:,:]
Out[10]:
data
idx1 idx2 idx3
1 1 0 1
1 1
2 1
In [11]: x
Out[11]:
data
idx1 idx2 idx3
1 1 0 1
1 1
2 1
2 1 3 1
4 1
2 0 1
1 1
2 1
3 1
4 1
这是正常现象吗?如何避免这种情况?
python 2.7 32 位,pandas==0.16.2,numpy==1.11.1+mkl
我认为更好的是 select 和 slicers
,它 return 相同的输出 - 所有级别:
x = pd.DataFrame({'idx1':[1]*10, 'idx2':[1]*5+[2]*5, 'idx3':list(range(5))+list(range(5)), 'data': [1]*10})
x = x.set_index(['idx1', 'idx2', 'idx3']).sortlevel()
print (x)
data
idx1 idx2 idx3
1 1 0 1
1 1
2 1
3 1
4 1
2 0 1
1 1
2 1
3 1
4 1
idx = pd.IndexSlice
print (x.loc[idx[1,:,:],:])
data
idx1 idx2 idx3
1 1 0 1
1 1
2 1
3 1
4 1
2 0 1
1 1
2 1
3 1
4 1
如果需要删除级别,请使用 xs
和参数 drop_level
:
print (x.xs(1, level=0, drop_level=True))
data
idx2 idx3
1 0 1
1 1
2 1
3 1
4 1
2 0 1
1 1
2 1
3 1
4 1
print (x.xs(1, level=0, drop_level=False))
data
idx1 idx2 idx3
1 1 0 1
1 1
2 1
3 1
4 1
2 0 1
1 1
2 1
3 1
4 1
第二个样本:
x = pd.DataFrame({'idx1':[1]*3+[2]*7, 'idx2':[1]*5+[2]*5, 'idx3':list(range(5))+list(range(5)), 'data': [1]*10})
x = x.set_index(['idx1', 'idx2', 'idx3']).sortlevel()
print (x)
data
idx1 idx2 idx3
1 1 0 1
1 1
2 1
2 1 3 1
4 1
2 0 1
1 1
2 1
3 1
4 1
idx = pd.IndexSlice
print (x.loc[idx[1,:,:],:])
data
idx1 idx2 idx3
1 1 0 1
1 1
2 1
print (x.xs(1, level=0, drop_level=True))
data
idx2 idx3
1 0 1
1 1
2 1
print (x.xs(1, level=0, drop_level=False))
data
idx1 idx2 idx3
1 1 0 1
1 1
2 1