pandas MultiIndex 在 0.15.2 和 0.18.0 之间使用 xs vs loc 生成的索引结构
pandas MultiIndex resulting index structure on using xs vs loc between 0.15.2 & 0.18.0
在具有 MultiIndex 的 DataFrame 上使用 .xs 和 .loc 对数据子集进行切片结果的索引结构似乎在 v0.15.2 和 0.18.0 之间发生了变化。
请参考使用不同版本的 Pandas.
在 ipython notebook 中获得的代码片段和输出
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
似乎return与原始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 位 (AMD64)]]
我认为这确实是一个错误,它也出现在更简单的设置中:
https://github.com/pydata/pandas/issues/12827
编辑: 好吧,可能不是,因为我在错误中制作的示例在 0.14.1 中的行为相同。
抱歉,忘了我的其他答案,我提交的错误完全无关。
正确答案是:"index structure" 在两个版本之间 没有 改变。唯一改变的是索引在打印时表示的方式。
在这两种情况下,您都有一个 MultiIndex,具有完全相同的级别和值。您可能对 0.18.0 中似乎包含 "baz" 和 "bar" 这一事实感到困惑。但是 MultiIndex
可以有它实际上不使用的级别值,因为在这个例子中,它在创建时包含它们,并且当使用它们的行被删除时,未使用的级别值不会被删除。 0.15.2 中的 sub_loc.index
在 levels
中也有 "baz" 和 "bar",只是打印时它的表示方式没有显示出来。
顺便说一下,过滤后的 MultiIndex 是否仍然包含这样的 "obsolete" 标签是您通常不应该关心的实现细节。也就是说,
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'])
出于实际目的 完全相同 索引,在 "having the same values in the same positions" 的意义上,因此在用于 Series
、DataFrame
s...
(您现在可能已经清楚了,MultiIndex
的 labels
组件决定了实际使用的级别值以及位置。)
在具有 MultiIndex 的 DataFrame 上使用 .xs 和 .loc 对数据子集进行切片结果的索引结构似乎在 v0.15.2 和 0.18.0 之间发生了变化。 请参考使用不同版本的 Pandas.
在 ipython notebook 中获得的代码片段和输出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
似乎return与原始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 位 (AMD64)]]
我认为这确实是一个错误,它也出现在更简单的设置中:
https://github.com/pydata/pandas/issues/12827
编辑: 好吧,可能不是,因为我在错误中制作的示例在 0.14.1 中的行为相同。
抱歉,忘了我的其他答案,我提交的错误完全无关。
正确答案是:"index structure" 在两个版本之间 没有 改变。唯一改变的是索引在打印时表示的方式。
在这两种情况下,您都有一个 MultiIndex,具有完全相同的级别和值。您可能对 0.18.0 中似乎包含 "baz" 和 "bar" 这一事实感到困惑。但是 MultiIndex
可以有它实际上不使用的级别值,因为在这个例子中,它在创建时包含它们,并且当使用它们的行被删除时,未使用的级别值不会被删除。 0.15.2 中的 sub_loc.index
在 levels
中也有 "baz" 和 "bar",只是打印时它的表示方式没有显示出来。
顺便说一下,过滤后的 MultiIndex 是否仍然包含这样的 "obsolete" 标签是您通常不应该关心的实现细节。也就是说,
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'])
出于实际目的 完全相同 索引,在 "having the same values in the same positions" 的意义上,因此在用于 Series
、DataFrame
s...
(您现在可能已经清楚了,MultiIndex
的 labels
组件决定了实际使用的级别值以及位置。)