Панды: T / F, если два диапазона пересекаются

1

У меня есть два кадра данных, которые могут выглядеть так:

df1:

name    start    end
stuart  0        20
lamp    32       34
hamlet  16       100

df2:

name    start    end
LOXL1   30       40
FOXP3   0        11
INSN    43       70

Я видел много ответов, которые находят пересечение между двумя диапазонами. Мой любимый:

range(max(start_1, start_2), min(end_1, end_2))

Это здорово. Но для моего контекста мне просто нужно знать, пересекаются ли оба диапазона. Кажется, я не могу найти ответ, который подходит для моего случая использования. Ожидаемый результат будет в основном захватывать имена из df2, для которых диапазон пересекается с df1. Ожидаемый результат:

name    start    end    intersects
stuart  0        20     FOXP3
lamp    32       34     LOXL1
hamlet  16       100    LOXL1|INSN

Или, если это проще (это решение будет фактически идеальным, но я могу работать с первым):

name    start    end    intersects
stuart  0        20     FOXP3
lamp    32       34     LOXL1
hamlet  16       100    LOXL1
hamlet  16       100    INSN

То, что я фактически застрял, - это получить True/False из того, пересекаются ли диапазоны между двумя строками, без цикла for. Цикл for не является жизнеспособным решением для меня, потому что у меня 40k строк сравнивается с 6m строк.

  • 0
    Являются ли start и end всегда целыми числами? Вы ожидаете, что перехваты будут редкими? Если так, может быть алгоритмическое ускорение относительно наивного подхода.
  • 0
    Start и End всегда целые числа, но я не уверен насчет разреженности перехватов.
Теги:
pandas
python-2.7

2 ответа

0

Просто используя математический способ + numpy broadcast

v1=df1.start.values
v2=df1.end.values
s1=df2.start.values
s2=df2.end.values
s=pd.DataFrame(((s2-v1[:,None])>0)&((s1-v2[:,None])<0)).dot(df2.name+'|').str[:-1]
s
Out[737]: 
0         FOXP3
1         LOXL1
2    LOXL1|INSN
dtype: object

#df1['New']=s.values
  • 0
    Это сработало очень хорошо, но у меня есть проблема: мой df2 имеет длину 1254113 строки. Для моего тестового примера df1 с 200 строками это все еще работало хорошо. Мой фактический df1 имеет 40000 строк (потенциально больше в будущем). Выполнение этого с df1 60 000 MemoryError . Есть ли у вас мысли по этому поводу?
  • 1
    @JohnRouhana вы можете разделить df1 на куски
Показать ещё 1 комментарий
0

Вопрос, на который вам нужно ответить, от того, что у вас уже есть, заключается в том, есть ли что-либо в range вы знаете.

if max(start_1, start_2) <= min(end_1, end_2):

Вы можете найти лучшие инструменты в модуле interval; это делает множество операций на известных интервалах; Я надеюсь, что есть инструменты с векторизованным инструментом, которые вы можете использовать.

  • 0
    Я не совсем уверен, что понимаю ваш ответ, но я проверю интервальный модуль. Спасибо за предложение.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню