Как я могу проверить, находится ли диапазон одного кадра данных в пределах диапазона другого кадра данных

#python #python-3.x #pandas #dataframe

Вопрос:

У меня есть 2 кадра данных, и я хочу проверить, находятся ли начальные и конечные диапазоны в DF1 в пределах начальных и конечных диапазонов в DF2, а для тех, которые верны, я хочу распечатать идентификатор и регион. Я хочу сравнить каждую строку DF1 с каждой строкой DF2.

Это мои фреймы данных:

 DF1 = pd.DataFrame ({'Start':[500, 850, 1000],
                    'End':[700, 950, 1200],
                    'Region':["A", "B", "C"]})

DF2 = pd.DataFrame ({'Start':[200, 800, 1100],
                    'End':[750, 950, 1250],
                    'ID':[1, 2, 3]})
 

DF1

Начать Конец Регион
500 700 A
850 950 B
1000 1200 C
1100 1500 D

DF2

Начать Конец ID
200 750 1
800 950 2
1100 1250 3

Я предполагаю, что мне нужно написать цикл for, чтобы выполнить итерацию по всем строкам. Тем не менее, я новичок, и мне трудно правильно настроить его.

Это код, который я пробовал до сих пор.

 for Start, End in DF1:
    if Start>=DF2["Start"] and End<=DF2["End"]:
      print (DF1["Region"], DF2["ID"])
 

Однако я получаю эту ошибку: ошибка значения: слишком много значений для распаковки (ожидается 2)

Любые советы о том, как решить эту проблему, будут весьма признательны.

Комментарии:

1. Пожалуйста, сделайте это полностью работающим сценарием, чтобы ответы можно было проверить. Инициализируйте DF1 и т. Д.

2. Вы просто сопоставляете каждую строку DF1 с одной и той же строкой в DF2, или каждый регион сравнивается с каждым идентификатором в DF2?

3. Я хочу проверить каждую строку DF1 на все строки DF2.

4. @pythonbeginner Тогда мое решение с перекрестным соединением должно соответствовать вашим требованиям.

5. @pythonbeginner Есть вопросы по решению ? Не стесняйтесь, дайте мне знать, если вам понадобятся какие-либо разъяснения.

Ответ №1:

Вы можете скрестить 2 .merge() кадра данных, а затем использовать .query() для фильтрации строк с требуемым условием, следующим образом:

 DF_out = DF1.merge(DF2, how='cross').query('(Start_x >= Start_y) amp; (End_x <= End_y)')
 

Если ваша версия Pandas старше 1.2.0 (версия от декабря 2020 года) и не поддерживает how='cross' , вы можете использовать:

 DF_out = DF1.assign(key=1).merge(DF2.assign(key=1), on='key').drop('key', axis=1).query('(Start_x >= Start_y) amp; (End_x <= End_y)')
 

Результат:

Start_x , End_x являются оригинальными Start , End столбцы в DF1

Start_y , End_y являются оригинальными Start , End столбцы в DF2

 print(DF_out)

   Start_x  End_x Region  Start_y  End_y  ID
0      500    700      A      200    750   1
4      850    950      B      800    950   2
 

Затем вы можете легко распечатать Region и ID , например

 print(DF_out['Region'])

0    A
4    B
Name: Region, dtype: object



print(DF_out['ID'])

0    1
4    2
Name: ID, dtype: int64
 

Если ваши критерии проверки строго < или > , а не <= или >= , вы можете изменить символы оператора сравнения в .query() , следующим образом:

 DF_out = DF1.merge(DF2, how='cross').query('(Start_x > Start_y) amp; (End_x < End_y)')
 

Результат:

 print(DF_out)

   Start_x  End_x Region  Start_y  End_y  ID
0      500    700      A      200    750   1
 

Комментарии:

1. @pythonbeginner Поскольку вам нужно проверить каждую строку DF1 на все строки DF2, вам неизбежно нужно выполнить некоторую аналогичную операцию, такую как перекрестное соединение. Как насчет того, чтобы разбить мои коды на 2 шага? То есть, получите результат .merge() в промежуточном кадре данных, а затем выполните фильтрацию с .query() помощью отдельного шага. Попробуй.

2. К сожалению, его разрыв также приводит к сбою Google colab. Я пытаюсь понять, как увеличить объем оперативной памяти.

3. @pythonbeginner Попробуйте разделить свои фреймы данных на небольшие фрагменты, запустите и объедините результаты. Например DF1 , разделите их на 4 части, каждая размером около 20000×3. Запустите коды 4 раза каждый с помощью одной из 4 разделенных частей. Что-то вроде того.

4. @pythonbeginner Вы уже нашли способ решить проблему с сбоем Google colab ? Недавно я нашел способ значительно ускорить процесс, а также снизить требования к хранению памяти. Посмотрим, не захотите ли вы попробовать мое новое решение. Дайте мне знать, если захотите.