Pandas MultiIndex选择值介于两个级别之间的行



我有一个DataFrame,它有一个具有3个级别namelowerupper的MultiIndex。我想查询name是某个特定值和某个数字nlower < n < upper(不一定是<,也可以是<=(的数据

import pandas as pd
df = pd.DataFrame({
'name': ['foo', 'foo', 'bar', 'bar'],
'lower': [0, 3, 0, 6],
'upper': [2, 5, 5, 11],
'some_data': [0, 1, 2, 3],
})
df = df.set_index(['name', 'lower', 'upper'], drop=True)
df = df.sort_index()
print(df)
#                   some_data
# name lower upper           
# bar  0     5              2
#      6     11             3
# foo  0     2              0
#      3     5              1
# Let's say I want to get the data where name is 'foo' and 1 is between lower and upper
print(df.loc[('foo', slice(None, 1), slice(1, None)), :])
#                   some_data
# name lower upper           
# foo  0     2              0

但现在我想要:

  • 其中name是"foo",1在lowerupper之间的数据
  • 其中name为"foo"且4在lowerupper之间的数据
  • name为"bar"且7位于lowerupper之间的数据

结果可能如下所示:

some_data
name contains  
foo  1                 0
foo  4                 1
bar  7                 3

一个接一个地做这件事很慢。有什么方法可以选择多行吗?

注意:我不必使用DataFrame,也不必使用MultiIndex。如果有更适合这份工作的数据结构,我会很乐意使用它。

您可以使用.between并传递列'A''B',而不必在以后将它们设置为级别。在下面的示例中,有两行'C'位于"A"one_answers"B"之间:

df = pd.DataFrame({
'A': [0, 3, 6, 9],
'B': [2, 5, 8, 11],
'C': [0, 1, 2, 10],
})
df_selected = df[df['C'].between(df['A'],df['B'])].set_index(['A', 'B'], drop=True)

结果:

C
A B     
0 2    0
9 11  10

区间索引适用于您的示例案例:

intervals = pd.IntervalIndex.from_arrays(df.index.get_level_values('lower'),
df.index.get_level_values('upper'), 
closed = 'both')
arr = intervals.get_indexer_for([1])
df.iloc[arr].loc['foo']

some_data
lower upper           
0     2              0

请为n的多个值添加更多的示例数据,如果可能的话,使多索引重叠

最新更新