Чтобы создать флаг для ключа на основе набора парных значений, присутствующих в фрейме данных 2 — Проблема Python

#python #pandas #jupyter-notebook

Вопрос:

Таблица A содержит два столбца — Col A и Анти Col A, так что, если значение из Col A входит в фрейм данных для идентификатора, Анти Col A не должно присутствовать — Если значение 1, то значение 4 не должно возникать.

Цель состоит в том, чтобы создавать флаг всякий раз, когда возникает такая ошибка.

введите описание изображения здесь

У меня есть таблица B, где в переменной ID указан ключ, и Col B должен следовать правилам таблицы A. Например: Для идентификатора «A», Col B содержит 1,2 и 3 в качестве значений. Но, согласно нашей таблице A, 2 не должно происходить вдоль стороны 3, следовательно, ошибка

введите описание изображения здесь

Конечный результат будет выглядеть следующим образом —

введите описание изображения здесь

Это образец, исходные данные содержат миллион строк.

Я пытался создать флаг для Col A и Анти Col A и найти решение, используя его с неудачной попыткой

введите описание изображения здесь

Часть 2 Как подойти к проблеме, если есть даты, добавленные вместе с существующим условием, т. е. Столбец «Анти» будет работать, если Дата начала и дата окончания являются активными входными данными — введите описание изображения здесь

Окончательный новый вывод — Например, для идентификаторов «B» 1 и 4 является антиправилом только для 1 и 2 июня. Хотя, по нашим данным, они прибудут 5 июня. следовательно, антиправило здесь неприменимо введите описание изображения здесь

Решение, приведенное в комментариях, работало ранее —

для каждой группы идентификаторов в df2 объедините все анти-col A для этой группы

тогда любое значение в текущей группе df2 должно быть помечено, если они находятся в этом пуле

 grouped = df2.groupby('ID').apply(lambda x: x['Col B'].isin(df1[df1['Col A'].isin(x['Col B'])]['Anti Col A'])).reset_index()
 

Добавление кода для создания фрейма данных, как упоминалось выше-

Фрейм данных — 1 и 2, как указано в коде

 df_1 = pd.DataFrame({'Col A': [1,2,3,4,5,6,6,6],
                   'Anti Col A': [4,5,2,2,1,7,1,3],
                   'Start Date': ['2021-06-01','2021-06-01','2021-06-01','2021-06-01','2021-06-01','2021-07-01','2021-06-01','2021-06-01'], 
                   'End Date': ['2021-06-02','2021-06-05','2021-06-02','2021-06-05','2021-06-05','2021-07-05','2021-06-05','2021-06-05']})

df_2 = pd.DataFrame({'ID': ['A','A','A','B','B','C','C','C','C'],
                   'Col B': [1,2,3,1,4,5,6,1,7],
                   'Start Date': ['2021-06-01','2021-06-02','2021-06-03','2021-06-04','2021-06-05','2021-05-06','2021-06-07','2021-06-08','2021-06-05'], 
                   'End Date': ['2021-06-01','2021-06-02','2021-06-03','2021-06-04','2021-06-05','2021-06-06','2021-06-07','2021-06-08','2021-06-09'],
                   'Flag_Old': [0,1,0,0,1,0,0,1,1],
                   'Flag_New': [0,1,0,0,0,0,0,0,1]})
 

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

1. Было бы действительно полезно, если бы вы опубликовали код в виде текста

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

3. @Da Song — Я добавил кадры данных в виде текста. Пожалуйста, дайте мне знать, если потребуется какая-либо другая информация для улучшения качества вопроса

Ответ №1:

Я попробовал это, и это работает, назовите два кадра данных df1 и df2 и предположите, что df2 не имеет дублированного значения с одинаковым идентификатором

 # for each ID group in df2, pool all the anti col A for this group
# then any value in current df2 group needs to be flag if they are in that pool
grouped = df2.groupby('ID').apply(lambda x: x['Col B'].isin(df1[df1['Col A'].isin(x['Col B'])]['Anti Col A'])).reset_index()

df2['Flag'] = grouped['Col B'].astype(int)
 

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

1. Песня , не хотели бы вы попробовать решить часть 2 проблемы? Чтобы разобраться с деталями, учитывая дату, будьте осторожны