在熊猫身上做多个关键横截面的方法似乎有三种:
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