【问题标题】:Pandas MultiIndex select rows where value is between two levelsPandas MultiIndex 选择值介于两个级别之间的行
【发布时间】:2022-01-25 09:21:18
【问题描述】:

我有一个带有 3 个级别的 MultiIndex 的 DataFrame namelowerupper。 我想查询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。如果有一些数据结构更适合这项工作,我很乐意使用它。

【问题讨论】:

  • 区间索引最适合这个
  • 请在您的数据框中添加更多行,并多解释一下您的想法。获取 C 在 A 和 B 之间的行,或 1 在 A 和 B 之间的行?
  • 区间索引是否可以处理重叠区间?
  • 好的,有一个错误阻止我在 MultiIndex github.com/pandas-dev/pandas/issues/25298 中使用区间索引
  • 请为n的多个值添加示例数据

标签: python pandas dataframe


【解决方案1】:

您可以使用.between 并传递'A''B' 列,而不必等到以后再使它们水平化。在下面的示例中,有两行 'C' 在“A”和“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

【讨论】:

    【解决方案2】:

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

    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 的多个值添加更多示例数据,如果可能,使 multiIndex 重叠

    【讨论】:

      猜你喜欢
      • 2022-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-10
      • 1970-01-01
      • 2020-06-05
      相关资源
      最近更新 更多