Как мне найти, где Series / DataFrame, содержащий интервалы, перекрывает данный интервал - PullRequest
0 голосов
/ 14 января 2019

У меня есть DataFrame с ценовыми диапазонами для некоторых предметов:

   price_low  price_high item
0         10          20    a
1          1           7    b
2         10          12    c
3         20          25    d
4          4           8    e
5          5          30    f
6         16          26    g

Как определить, какие предметы перекрывают данный ценовой диапазон, скажем, от 8 до 16 долларов?

Ожидаемый результат:

   price_low  price_high item
0         10          20    a
2         10          12    c
4          4           8    e
5          5          30    f
6         16          26    g

Ответы [ 2 ]

0 голосов
/ 14 января 2019

ответ root является общим и информативным. Если вы ищете быстрое решение для простых случаев, вы можете попробовать ниже

df[(df['price_low']<=16)&(df['price_high']>=8)]

Это условие для двух интервалов, которые должны перекрываться. Так проще понять: нижняя граница ценового диапазона (8) не должна быть выше, чем price_high, а его верхняя граница (16) не должна быть ниже, чем price_low.

0 голосов
/ 14 января 2019

Начиная с панд 0.24.0, вы можете использовать метод IntervalArray.overlaps или, альтернативно, метод IntervalIndex.overlaps:

# construct the IntervalArray
price_ivs = pd.arrays.IntervalArray.from_arrays(df['price_low'], df['price_high'], closed='both')

# define desired price Interval and use the overlaps method to restrict df
my_price = pd.Interval(8, 16, closed='both')
df = df[price_ivs.overlaps(my_price)]

Для интерактивной демонстрации сначала создайте пример данных:

In [1]: import pandas as pd; pd.__version__
Out[1]: '0.24.0rc1'

In [2]: df = pd.DataFrame({
   ...:     'price_low': [10, 1, 10, 20, 4, 5, 16],
   ...:     'price_high': [20, 7, 12, 25, 8, 30, 26],
   ...:     'item': list('abcdefg')
   ...: })

In [3]: df
Out[3]: 
   price_low  price_high item
0         10          20    a
1          1           7    b
2         10          12    c
3         20          25    d
4          4           8    e
5          5          30    f
6         16          26    g

Построить IntervalArray из DataFrame:

In [4]: price_ivs = pd.arrays.IntervalArray.from_arrays(
   ...:     df['price_low'], df['price_high'], closed='both')

In [5]: price_ivs
Out[5]: 
IntervalArray([[10, 20], [1, 7], [10, 12], [20, 25], [4, 8], [5, 30], [16, 26]],
              closed='both',
              dtype='interval[int64]')

Определите желаемую цену Interval и используйте метод overlaps, чтобы получить логический индексатор:

In [6]: my_price = pd.Interval(8, 16, closed='both')

In [7]: idxr = price_ivs.overlaps(my_price)

In [8]: idxr
Out[8]: array([ True, False,  True, False,  True,  True,  True])

In [9]: df[idxr]
Out[9]: 
   price_low  price_high item
0         10          20    a
2         10          12    c
4          4           8    e
5          5          30    f
6         16          26    g

Если у вас уже есть столбец цен в качестве интервалов (или Series интервалов), вы можете использовать атрибут array для доступа к базовому IntervalArray и использовать тот же метод, что и выше:

In [10]: df = pd.DataFrame({'price_ivs': price_ivs, 'item': list('abcdefg')})

In [11]: df
Out[11]: 
  price_ivs item
0  [10, 20]    a
1    [1, 7]    b
2  [10, 12]    c
3  [20, 25]    d
4    [4, 8]    e
5   [5, 30]    f
6  [16, 26]    g

In [12]: idxr = df['price_ivs'].array.overlaps(my_price)

In [13]: idxr
Out[13]: array([ True, False,  True, False,  True,  True,  True])

In [14]: df[idxr]
Out[14]: 
  price_ivs item
0  [10, 20]    a
2  [10, 12]    c
4    [4, 8]    e
5   [5, 30]    f
6  [16, 26]    g
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...