在熊猫身上做多个关键横截面的方法似乎有三种:
Using pd.IndexSlice
Using groupby's filter
Converting to panel, getting the cross-section, and converting back again to DataFrame
但是,我无法运行这些线程中描述的解决方案。让我解释一下:
使用idx的示例:
假设我想从以下系列中获得与['bar', 'flux']相关联的截面A

> my_series

A    B
bar  one    0.269566
     three  1.156823
flux six    0.087296
     three -2.652280
foo  five   0.216790
     one   -0.652412
     two    0.590229
     two   -1.570565

如果我这样做了:
> idx = pd.IndexSlice
> my_series.to_frame().loc[idx[['bar', 'flux'],:], :]

我得到:
A    B
bar  one    0.269566
     three  1.156823
flux six    0.087296
     three -2.652280

这是正确的(它给出了['bar', 'flux']的横截面。
使用idx失败(键不存在)的示例:
现在,假设我在不存在的横截面键列表中包含一个键(例如does_not_exist),我得到:
> my_series.to_frame().loc[idx[['bar', 'does_not_exist'],:], :]

KeyError: 'does_not_exist'

但是,如果我不知道does_not_exist在水平A中不存在的先验知识怎么办?如何避免错误,并仍然从请求的横截面获取匹配项?如何正确地预修剪关键点以确保横截面与任何匹配的关键点一起工作?
另外,在上面的例子中,我是否需要通过一个框架来使用idx?如果我直接使用它,我会得到:
> idx = pd.IndexSlice
> my_series[idx[['bar', 'something_else'],:], :]
TypeError:

为什么?
using the "panel" solution时失败(重复索引)的示例:
相反,如果我尝试my_series.to_frame().to_panel().ix[:,my_keys, :]得到:
ValueError: Can't convert non-uniquely index DataFrame to Panel

但我想我可以使用this answer中描述的“转换为面板”解决方案来获得横截面。为什么会失败?
附录:
为了创建我在文章顶部作为示例包含的随机序列,我使用了:
def create_random_multi_index():
  df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar',
                            'foo', 'flux', 'foo', 'flux'],
                     'B' : ['one', 'one', 'two', 'three',
                            'two', 'six', 'five', 'three'],
                     'C' : randn(8), 'D' : randn(8), 'E': randint(0,3, size=(8,))})
  df.set_index(['A', 'B'], inplace=True)
  df.sort_index(inplace=True)
  return df

然后我做了(例如):
my_series = create_random_multi_index['C']

或者,您可以使用:
s = Series(np.arange(9),index=pd.MultiIndex.from_product([['A','B','C'],['foo','bar','baz']],names=['one','two'])).sortlevel()

最佳答案

我认为这可能是一个API问题,请参见:https://github.com/pydata/pandas/issues/7866。我认为这可能也应该奏效。
创建示例数据。一般来说,请确保它是按词法排序的。

In [17]: s = Series(np.arange(9),index=pd.MultiIndex.from_product([['A','B','C'],['foo','bar','baz']],names=['one','two'])).sortlevel()

In [21]: s
Out[21]:
one  two
A    bar    1
     baz    2
     foo    0
B    bar    4
     baz    5
     foo    3
C    bar    7
     baz    8
     foo    6
dtype: int64

常规选择。如果找不到值,则会提升KeyError
In [18]: s.loc[idx[:,'foo']]
Out[18]:
one
A      0
B      3
C      6
dtype: int64

用面具来选择。这里,无论值是否存在,掩码都是布尔数组。
In [19]: s.loc[idx[:,s.index.get_level_values('two').isin(['foo','bah'])]]
Out[19]:
one  two
A    foo    0
B    foo    3
C    foo    6
dtype: int64

可能更容易重新编制索引。
In [20]: s.reindex(['foo','bah'],level='two')
Out[20]:
one  two
A    foo    0
B    foo    3
C    foo    6
dtype: int64

09-25 18:13