Как удалить строки в Pandas DF, если значение из столбца A находится в столбце B, а столбец C соответствует - PullRequest
0 голосов
/ 03 апреля 2020

У меня есть фрейм данных с некоторой информацией о пользователе / ​​файле. Например:

| Scanned_Item | Matched_Item | Owner_Name |
|      item 1  |     item 2   |    owner 1 |
|      item 1  |     item 3   |    owner 1 |
|      item 3  |     item 1   |    owner 2 |

У меня есть несколько тысяч предметов. Возможно, Matched_Items не будет Scanned_Item. Я пытаюсь удалить все строки, в которых Scanned_Item и Matched_Item принадлежат одному и тому же человеку.

Мой желаемый вывод - это DF, в котором ни один владелец не сопоставляет свои собственные элементы, таким образом удаляя самодублирование. Я хочу видеть только те строки, в которых владелец сопоставляет чужой файл.

Эквивалентно тому, что Matched_Item существует в Scanned_Item и Owner_Name для Matched_Item = Owner_Name для Scanned_Item.

(Совпадение формируется на основе других заранее определенных критериев, которые на самом деле не имеют отношения к этой проблеме.

Редактировать: это то, что я написал сейчас, но это занимает вечность, не уверен, если это признак того, что он не работает, ха.

for index, row in df.iterrows():
    for index2, row2 in df.iterrows():
        if row['Scanned_Workbook'] == row2['Matched_Workbook'] and row['Full Name'] == row2['Full Name']:
            df.drop(index,errors='ignore')
            df.drop(index2,errors='ignore')

Edit2: как дополнительная деталь, так как Кажется, есть некоторые проблемы с ясностью. Все отсканированные и сопоставленные элементы были получены из одного и того же исходного источника данных. Я нашел совпадающие элементы, выполнив итерацию в моем исходном наборе данных и используя Python понимание набора, чтобы найти файлы, в которых соответствовали три критерия.

Таким образом, элемент 1 был отсканирован и соответствует 3 критериям с элементом 2. Вот откуда берется первая строка. Но из-за того, как я понял, у меня есть только имя владельца для Scanned_Items, а не Matched_Items.

Я пытаюсь удалить все строки, где Scanned_Item и Matched_Item - bo принадлежит одному владельцу.

Помогает ли это для ясности?

Edit3: Вот пример строк, которые будут удалены.

| Scanned_Item | Matched_Item | Owner_Name |
|      item 1  |     item 2   |    owner 1 |
|      item 2  |     item 1   |    owner 1 |

Поскольку оба элемента 1 и 2 были отсканированы в некоторых Дык, они совпали друг с другом. Но у них тоже есть один и тот же владелец. Я хочу удалить любые строки, которые выглядят так.

Имя владельца привязано к отсканированному предмету. Таким образом, единственный способ найти владельца соответствующего элемента - это найти его в отсканированном столбце.

Ответы [ 3 ]

0 голосов
/ 03 апреля 2020

Я бы разделил задачу на два шага

  1. сопоставил бы каждый item с owner
  2. , применил логическую маску для фильтрации на основе шага 1

Шаг 1: сопоставьте owners с items. Мы могли бы сделать это с помощью словаря. Предполагая, что Matched_Item является элементом, связанным с Owner_Name,

df_owner_items = df[["owner_name", "matched_item"]].          \
                     drop_duplicates().                       \  # We select only non duplicated records
                     set_index("matched_item")                \  # We set index to use the `from_dict` method later in the most useful way
owner_items_dict = df_owner_items.to_dict(orient="index")        # Our dataframe is transformed in a dictionary having format {"item1": {"owner_name": "owner 1"}}

Шаг 2: создайте логическую маску и фильтр

filter = (df["owner_name"] != owner_items_dict["matched_item"]["owner_name"])
filtered_df = df.loc[filter]

Надеюсь, это поможет.

0 голосов
/ 03 апреля 2020

Пошел другой путь для решения проблемы. Я просто соединил исходный набор данных и нашел владельца matched_items, чтобы иметь возможность сканировать и сопоставлять владельцев в отдельных столбцах. Затем, используя df.query, удалил все строки, в которых совпали два значения владельца.

Это решило мою проблему, спасибо всем, кто ответил / прокомментировал.

0 голосов
/ 03 апреля 2020

Если я правильно понимаю, вам нужно удалить дубликаты.

Почему бы просто не написать следующее, если вы хотите удалить все эти строки:

new_df = df.drop_duplicates(keep=False)

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

new_df = df.drop_duplicates(keep='first')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...