我有一些带有MultiIndex的数据(一些时序统计信息,以及“设备”,“构建配置”,“测试功能”等的索引级别)。我想对其中一些索引列进行切片。
.loc函数的“切片器”似乎是可行的方法。但是文档包含以下警告:
警告:您需要确保选择轴已完全按照顺序排列!
后来在文档中有一个部分需要有序性与多指标其说
您有责任确保物品正确分类
但幸运的是,
MultiIndex对象具有用于显式检查排序深度的代码。因此,如果尝试在未对索引进行排序的深度进行索引,则会引发异常。
听起来不错。
但是,剩下的问题是如何使他们的数据正确排序以使索引正常工作?文档讨论了一种重要的新方法,sortlevel()
但随后包含以下警告:
有一个重要的新方法sortlevel可以对MultiIndex中的轴进行排序,以便按该级别上关联因子的原始顺序对标签进行分组和排序。请注意,这并不一定意味着标签将按字典顺序排序!
在我的情况下,sortlevel()做对了,但是如果我的“相关因子的原始排序”没有排序怎么办?是否可以在任何MultiIndex-ed DataFrame上使用一个简单的单行代码,以确保它已准备好进行切片和完全按词法排序?
编辑:我的探索建议,大多数创建MultiIndex的方法都会在建立索引时自动对唯一标签进行lexsort。例:
In [1]:
import pandas as pd
df = pd.DataFrame({'col1': ['b','d','b','a'], 'col2': [3,1,1,2],
'data':['one','two','three','four']})
df
Out[1]:
col1 col2 data
0 b 3 one
1 d 1 two
2 b 1 three
3 a 2 four
In [2]:
df2 = df.set_index(['col1','col2'])
df2
Out[2]:
data
col1 col2
b 3 one
d 1 two
b 1 three
a 2 four
In [3]: df2.index
Out[3]:
MultiIndex(levels=[[u'a', u'b', u'd'], [1, 2, 3]],
labels=[[1, 2, 1, 0], [2, 0, 0, 1]],
names=[u'col1', u'col2'])
Run Code Online (Sandbox Code Playgroud)
请注意,即使DataFrame对象本身不是,也对levels数组中的唯一项进行了分类。然后,按预期方式:
In [4]: df2.index.is_lexsorted()
Out[4]: False
In [5]:
sorted = df2.sortlevel()
sorted
Out[5]:
data
col1 col2
a 2 four
b 1 three
3 one
d 1 two
In [6]: sorted.index.is_lexsorted()
Out[6]: True
Run Code Online (Sandbox Code Playgroud)
但是,如果对级别进行了显式排序,则未对它们进行排序,那么事情就会变得很奇怪:
In [7]:
df3 = df2
df3.index.set_levels(['b','d','a'], level='col1', inplace=True)
df3.index.set_labels([0,1,0,2], level='col1', inplace=True)
df3
Out[7]:
data
col1 col2
b 3 one
d 1 two
b 1 three
a 2 four
In [8]:
sorted2 = df3.sortlevel()
sorted2
Out[8]:
data
col1 col2
b 1 three
3 one
d 1 two
a 2 four
In [9]: sorted2.index.is_lexsorted()
Out[9]: True
In [10]: sorted2.index
Out[10]:
MultiIndex(levels=[[u'b', u'd', u'a'], [1, 2, 3]],
labels=[[0, 0, 1, 2], [0, 2, 0, 1]],
names=[u'col1', u'col2'])
Run Code Online (Sandbox Code Playgroud)
因此sorted2报告它是按词法排序的,而实际上不是。这听起来有点像文档中的警告内容,但是仍然不清楚如何解决它,或者它是否真的是一个问题。
至于排序,正如 @EdChum 指出的那样,这里的文档似乎表明它是按字典顺序排序的。
为了检查您的索引(或列)是否已排序,它们有一个方法is_lexsorted()
和一个属性lexsort_depth
(由于某种原因您无法在文档本身中找到)。
例子:
创建随机顺序的系列
In [1]:
import pandas as pd
arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
['one', 'two', '1', '3', 'one', 'two', 'one', 'two']]
tuples = list(zip(*arrays))
import random; random.shuffle(tuples)
s = pd.Series(np.random.randn(8), index=pd.MultiIndex.from_tuples(tuples))
s
Out[1]:
baz 3 -0.191653
qux two -1.410311
bar one -0.336475
qux one -1.192908
foo two 0.486401
baz 1 0.888314
foo one -1.504816
bar two 0.917460
dtype: float64
Run Code Online (Sandbox Code Playgroud)
检查 is_lexsorted 和 lexsort_深度:
In [2]: s.index.is_lexsorted()
Out[2]: False
In [3]: s.index.lexsort_depth
Out[3]: 0
Run Code Online (Sandbox Code Playgroud)
对索引进行排序,然后重新检查值:
In [4]: s = s.sortlevel(0, sort_remaining=True)
s
Out[4]:
bar one -0.336475
two 0.917460
baz 1 0.888314
3 -0.191653
foo one -1.504816
two 0.486401
qux one -1.192908
two -1.410311
dtype: float64
In [5]: s.index.is_lexsorted()
Out[5]: True
In [6]: s.index.lexsort_depth
Out[6]: 2
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1397 次 |
最近记录: |