У меня есть два фрейма данных панд, у которых есть несколько общих строк.
Предположим, dataframe2 является подмножеством dataframe1.
Как я могу получить строки dataframe1, которых нет в dataframe2?
df1 = pandas.DataFrame(data = {'col1' : [1, 2, 3, 4, 5], 'col2' : [10, 11, 12, 13, 14]})
df2 = pandas.DataFrame(data = {'col1' : [1, 2, 3], 'col2' : [10, 11, 12]})
Ответы:
Одним из методов было бы сохранить результат внутренней формы слияния обоих dfs, тогда мы можем просто выбрать строки, когда значения одного столбца находятся не в этом общем:
РЕДАКТИРОВАТЬ
Вы нашли еще один метод,
isin
который будет использоватьNaN
строки, которые вы можете удалить:Однако, если df2 не запускает строки таким же образом, это не будет работать:
будет производить весь DF:
источник
df1[~df1.isin(df2)].dropna(how = 'all')
кажется, добивается цели. В любом случае, спасибо - ваш ответ помог мне найти решение.isin
требует, чтобы оба dfs начинались с одинаковых значений строк, например, если df2 был,df2 = pd.DataFrame(data = {'col1' : [2, 3,4], 'col2' : [11,12, 13]})
тогда ваш метод не будет работатьkeep=False
:df0.append(df1).drop_duplicates(keep=False)
по умолчанию он сохраняет первый дубликат, вы хотите удалить все дубликатыТекущее выбранное решение дает неверные результаты. Чтобы правильно решить эту проблему, мы можем выполнить левое соединение от
df1
доdf2
, убедившись, что сначала получим только уникальные строки дляdf2
.Во-первых, нам нужно изменить исходный DataFrame, чтобы добавить строку с данными [3, 10].
Выполните левое соединение, исключив дубликаты,
df2
чтобы каждый рядdf1
объединялся с ровно 1 строкойdf2
. Используйте параметр,indicator
чтобы получить дополнительный столбец, в котором указано, из какой таблицы была получена строка.Создайте логическое условие:
Почему другие решения неверны
Несколько решений допускают одну и ту же ошибку - они только проверяют, что каждое значение независимо в каждом столбце, а не вместе в одной строке. Добавление последней строки, которая является уникальной, но имеет значения из обоих столбцов,
df2
выявляет ошибку:Это решение дает тот же неправильный результат:
источник
df_all[df_all['_merge'] == 'left_only']
чтобы иметь df с результатамиПредполагая, что индексы согласованы в кадрах данных (без учета фактических значений col):
источник
df1
которых индексы НЕ находятсяdf2.index
». Подробнее об отрицании: stackoverflow.com/q/19960077/304209 (удивительно, я не смог найти упоминаний о тильде в документах панд).ValueError: Item wrong length x instead of y.
Как уже указывалось, isin требует, чтобы столбцы и индексы были одинаковыми для совпадения. Если соответствие должно быть только для содержимого строки, один из способов получить маску для фильтрации имеющихся строк - преобразовать строки в (мульти) индекс:
Если индекс должен быть принят во внимание, set_index имеет ключевое слово аргумент, добавляющий столбцы к существующему индексу. Если столбцы не совпадают, список (df.columns) можно заменить спецификациями столбцов для выравнивания данных.
в качестве альтернативы можно использовать для создания индексов, хотя я сомневаюсь, что это более эффективно.
источник
Предположим, у вас есть два кадра данных, df_1 и df_2, имеющие несколько полей (имена столбцов), и вы хотите найти только те записи в df_1, которые не находятся в df_2 на основе некоторых полей (например, fields_x, fields_y), выполните следующие шаги.
Шаг 1. Добавьте столбец key1 и key2 к df_1 и df_2 соответственно.
Step2.Merge фреймы данных, как показано ниже. field_x и field_y - наши желаемые столбцы.
Step3.Выберите только те строки из df_1, где key1 не равен key2.
Шаг 4. Удалите ключ1 и ключ2.
Этот метод решит вашу проблему и работает быстро даже с большими наборами данных. Я пробовал это для фреймов данных с более чем 1 000 000 строк.
источник
немного поздно, но, возможно, стоит проверить параметр «индикатора» в pd.merge.
Посмотрите на этот другой вопрос для примера: сравните PandaS DataFrames и верните строки, которые отсутствуют в первом
источник
Вы можете сделать это, используя метод isin (dict) :
Объяснение:
источник
Вы также можете Concat
df1
,df2
:а затем удалите все дубликаты:
источник
Как насчет этого:
источник
Вот еще один способ решения этой проблемы:
Или:
источник
Мой способ сделать это включает добавление нового столбца, уникального для одного кадра данных, и использование этого, чтобы выбрать, сохранять ли запись
Это делает так, чтобы каждая запись в df1 имела код - 0, если он уникален для df1, 1, если он находится в обоих фреймах данных. Затем вы используете это, чтобы ограничить то, что вы хотите
источник
источник