pandas MultiIndex使用xs vs loc在0.15.2&之间得到索引结构。 0.18.0

时间:2016-04-06 18:21:42

标签: pandas multi-index

使用.xs&amp ;;切割数据子集的结果的索引结构带有MultiIndex的DataFrame上的.loc似乎在v0.15.2&之间发生了变化。 0.18.0开始。 请参阅代码段&使用不同版本的Pandas在ipython笔记本中输出。

import pandas as pd
print 'pandas-version: ', pd.__version__
import numpy as np
l1 = ['A', 'B', 'C', 'D']
l2 = sorted(['foo','bar','baz'])
nrows = len(l1) * len(l2)
s = pd.DataFrame(np.random.random( nrows * 2).reshape(nrows, 2),
                 index=pd.MultiIndex.from_product([l1, l2],
                                                 names=['one','two']))

# print s.index
l_all = slice(None)
# get all records matching 'foo' in level=1 using .loc
sub_loc = s.loc[(l_all, 'foo'),:]
print '.loc[(slice(None), "foo")] result:\n', sub_loc, 
print '\n.loc result-index:\n', sub_loc.index

# get all records matching 'foo' in level=1 using .xs()
sub_xs = s.xs('foo', level=1)
print '\n.xs(\'foo\', level=1) result:\n', sub_xs, 
print '\n .xs result index:\n', sub_xs.index

0.15.2输出

#######################
pandas-version:  0.15.2
.loc[(slice(None), "foo")] result:
                0         1
one two                    
A   foo  0.464551  0.372409
B   foo  0.782062  0.268917
C   foo  0.779423  0.787554
D   foo  0.481901  0.232887 
.loc result-index:
one  two
A    foo
B    foo
C    foo
D    foo

.xs('foo', level=1) result:
            0         1
one                    
A    0.464551  0.372409
B    0.782062  0.268917
C    0.779423  0.787554
D    0.481901  0.232887 
 .xs result index:
Index([u'A', u'B', u'C', u'D'], dtype='object')

0.18.0输出

##########################
pandas-version:  0.18.0
.loc[(slice(None), "foo")] result:
                0         1
one two                    
A   foo  0.723213  0.532838
B   foo  0.736941  0.401252
C   foo  0.217131  0.044254
D   foo  0.712824  0.411026 
.loc result-index:
MultiIndex(levels=[[u'A', u'B', u'C', u'D'], [u'bar', u'baz', u'foo']],
           labels=[[0, 1, 2, 3], [2, 2, 2, 2]],
           names=[u'one', u'two'])

.xs('foo', level=1) result:
            0         1
one                    
A    0.723213  0.532838
B    0.736941  0.401252
C    0.217131  0.044254
D    0.712824  0.411026 
 .xs result index:
Index([u'A', u'B', u'C', u'D'], dtype='object', name=u'one')

调用sub_loc.index似乎返回原始DataFrame对象的相同MultiIndex结构(与v0.15.2不一致),但sub_xs.index似乎与早期版本一致。

注意:我使用的是[Python 2.7.11 | Anaconda 1.8.0(64位)| (默认,2016年2月16日,09:58:36)[MSC v.1500 64 bit(AMD64)]]

2 个答案:

答案 0 :(得分:0)

我认为这确实是一个错误,它也出现在更简单的设置中:

https://github.com/pydata/pandas/issues/12827

编辑:好吧,可能不是,因为我在bug中做的例子在0.14.1中表现相同。

答案 1 :(得分:0)

抱歉,忘记我的其他答案,我提交的错误完全不相关。

正确的答案是:"索引结构"两个版本之间的已更改。唯一改变的是打印时索引代表的方式。

在这两种情况下,您都有一个MultiIndex,具有完全相同的级别和值。你可能会感到困惑的是,在0.18.0中它似乎包含了" baz" &" bar"。但是MultiIndex可以具有它实际上不使用的级别值,因为,如在此示例中,它在创建时包含它们,并且当使用它们的行被删除时未使用的级别值不被消除。 0.15.2中的sub_loc.index也有" baz"和" bar"在levels内,除了打印时它的表示方式并没有显示出来。

顺便说一句,过滤后的MultiIndex是否仍包含这样的"过时"标签与否是您通常不应该关注的实现细节。换句话说,

MultiIndex(levels=[[u'A', u'B', u'C', u'D'], [u'bar', u'baz', u'foo']],
       labels=[[0, 1, 2, 3], [2, 2, 2, 2]],
       names=[u'one', u'two'])

MultiIndex(levels=[[u'A', u'B', u'C', u'D'], [u'foo']],
       labels=[[0, 1, 2, 3], [0, 0, 0, 0]],
       names=[u'one', u'two'])

用于实际目的完全相同的索引,在"意义上相同的位置"具有相同的值,因此在用于{{之间的赋值时表现相同1}},Series s ...

(正如你现在已经清楚的那样,DataFrame的{​​{1}}组件决定了实际使用哪些级别的值,以及在哪些位置。)