我有一个DataFrame,它有一个具有3个级别name
、lower
和upper
的MultiIndex。我想查询name
是某个特定值和某个数字n
lower < 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在lower
和upper
之间的数据 - 其中
name
为"foo"且4在lower
和upper
之间的数据 name
为"bar"且7位于lower
和upper
之间的数据
结果可能如下所示:
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的多个值添加更多的示例数据,如果可能的话,使多索引重叠