met*_*mit 19 python hierarchical multi-index pandas
我有DataFrame和MultiIndex列,如下所示:
# sample data
col = pd.MultiIndex.from_arrays([['one', 'one', 'one', 'two', 'two', 'two'],
['a', 'b', 'c', 'a', 'b', 'c']])
data = pd.DataFrame(np.random.randn(4, 6), columns=col)
data
Run Code Online (Sandbox Code Playgroud)

['a', 'c']从第二级别仅选择特定列(例如,不是范围)的正确,简单方法是什么?
目前我这样做:
import itertools
tuples = [i for i in itertools.product(['one', 'two'], ['a', 'c'])]
new_index = pd.MultiIndex.from_tuples(tuples)
print(new_index)
data.reindex_axis(new_index, axis=1)
Run Code Online (Sandbox Code Playgroud)

然而,它不是一个好的解决方案,因为我必须淘汰itertools,手工构建另一个MultiIndex,然后重新索引(我的实际代码甚至更麻烦,因为列列表不是那么容易获取).我很确定必须有一些ix或xs这样做,但我尝试的一切都导致了错误.
Gui*_*omé 24
最直接的方法是.loc:
>>> data.loc[:, (['one', 'two'], ['a', 'b'])]
one two
a b a b
0 0.4 -0.6 -0.7 0.9
1 0.1 0.4 0.5 -0.3
2 0.7 -1.6 0.7 -0.8
3 -0.9 2.6 1.9 0.6
Run Code Online (Sandbox Code Playgroud)
记住这一点[]并()在处理MultiIndex对象时具有特殊含义:
(...) 元组被解释为一个多级键
(...) 一个列表用于指定几个键 [在同一级别]
(...) 一个列表元组引用一个级别中的几个值
当我们编写 时(['one', 'two'], ['a', 'b']),元组中的第一个列表指定了我们想要从MultiIndex. 元组中的第二个列表指定了我们想要从MultiIndex.
编辑 1:另一种可能性是用于slice(None)指定我们想要来自第一级的任何内容(工作方式类似于:在列表中切片)。然后指定我们想要的第二级中的哪些列。
>>> data.loc[:, (slice(None), ["a", "b"])]
one two
a b a b
0 0.4 -0.6 -0.7 0.9
1 0.1 0.4 0.5 -0.3
2 0.7 -1.6 0.7 -0.8
3 -0.9 2.6 1.9 0.6
Run Code Online (Sandbox Code Playgroud)
如果语法slice(None)确实吸引您,那么另一种可能性是使用pd.IndexSlice,这有助于使用更精细的索引对帧进行切片。
>>> data.loc[:, pd.IndexSlice[:, ["a", "b"]]]
one two
a b a b
0 0.4 -0.6 -0.7 0.9
1 0.1 0.4 0.5 -0.3
2 0.7 -1.6 0.7 -0.8
3 -0.9 2.6 1.9 0.6
Run Code Online (Sandbox Code Playgroud)
使用时pd.IndexSlice,我们可以:像往常一样使用对帧进行切片。
来源:MultiIndex/Advanced Indexing,如何使用slice(None)
Foo*_*Bar 16
我认为有一个更好的方法(现在),这就是为什么我打扰这个问题(这是最好的谷歌结果)出于阴影:
data.select(lambda x: x[1] in ['a', 'b'], axis=1)
Run Code Online (Sandbox Code Playgroud)
以快速,干净的单行提供您的预期输出:
one two
a b a b
0 -0.341326 0.374504 0.534559 0.429019
1 0.272518 0.116542 -0.085850 -0.330562
2 1.982431 -0.420668 -0.444052 1.049747
3 0.162984 -0.898307 1.762208 -0.101360
Run Code Online (Sandbox Code Playgroud)
它主要是自我解释,[1]指的是水平.
Vik*_*kez 14
您可以使用其中任何一个,loc或者ix我将展示一个示例loc:
data.loc[:, [('one', 'a'), ('one', 'c'), ('two', 'a'), ('two', 'c')]]
Run Code Online (Sandbox Code Playgroud)
如果您有MultiIndexed DataFrame,并且只想过滤掉某些列,则必须传递与这些列匹配的元组列表.所以itertools方法非常好,但您不必创建新的MultiIndex:
data.loc[:, list(itertools.product(['one', 'two'], ['a', 'c']))]
Run Code Online (Sandbox Code Playgroud)
这不是很好,但也许:
>>> data
one two
a b c a b c
0 -0.927134 -1.204302 0.711426 0.854065 -0.608661 1.140052
1 -0.690745 0.517359 -0.631856 0.178464 -0.312543 -0.418541
2 1.086432 0.194193 0.808235 -0.418109 1.055057 1.886883
3 -0.373822 -0.012812 1.329105 1.774723 -2.229428 -0.617690
>>> data.loc[:,data.columns.get_level_values(1).isin({"a", "c"})]
one two
a c a c
0 -0.927134 0.711426 0.854065 1.140052
1 -0.690745 -0.631856 0.178464 -0.418541
2 1.086432 0.808235 -0.418109 1.886883
3 -0.373822 1.329105 1.774723 -0.617690
Run Code Online (Sandbox Code Playgroud)
会工作?
要选择所有已命名的列'a'以及'c'列索引器的第二级,可以使用切片器:
>>> data.loc[:, (slice(None), ('a', 'c'))]
one two
a c a c
0 -0.983172 -2.495022 -0.967064 0.124740
1 0.282661 -0.729463 -0.864767 1.716009
2 0.942445 1.276769 -0.595756 -0.973924
3 2.182908 -0.267660 0.281916 -0.587835
Run Code Online (Sandbox Code Playgroud)
在这里您可以阅读有关切片机的更多信息
ix并select已弃用!使用的pd.IndexSlice品牌loc更可取的选择,以ix和select。
DataFrame.loc 与 pd.IndexSlice# Setup
col = pd.MultiIndex.from_arrays([['one', 'one', 'one', 'two', 'two', 'two'],
['a', 'b', 'c', 'a', 'b', 'c']])
data = pd.DataFrame('x', index=range(4), columns=col)
data
one two
a b c a b c
0 x x x x x x
1 x x x x x x
2 x x x x x x
3 x x x x x x
Run Code Online (Sandbox Code Playgroud)
data.loc[:, pd.IndexSlice[:, ['a', 'c']]]
one two
a c a c
0 x x x x
1 x x x x
2 x x x x
3 x x x x
Run Code Online (Sandbox Code Playgroud)
您还可以选择一个axis参数,loc以使其明确指出要从哪个轴索引:
data.loc(axis=1)[pd.IndexSlice[:, ['a', 'c']]]
one two
a c a c
0 x x x x
1 x x x x
2 x x x x
3 x x x x
Run Code Online (Sandbox Code Playgroud)
MultiIndex.get_level_values调用data.columns.get_level_values过滤器loc是另一种选择:
data.loc[:, data.columns.get_level_values(1).isin(['a', 'c'])]
one two
a c a c
0 x x x x
1 x x x x
2 x x x x
3 x x x x
Run Code Online (Sandbox Code Playgroud)
这自然可以允许在单个级别上对任何条件表达式进行过滤。这是一个按字典顺序过滤的随机示例:
data.loc[:, data.columns.get_level_values(1) > 'b']
one two
c c
0 x x
1 x x
2 x x
3 x x
Run Code Online (Sandbox Code Playgroud)
有关对MultiIndex进行切片和过滤的更多信息,请参见pandas MultiIndex DataFrame中的Select行。
| 归档时间: |
|
| 查看次数: |
12731 次 |
| 最近记录: |