Удалить одинаковые строки определенных столбцов двух датафреймов
Датафрейм df1:
A B C D
0 256 4 24 51
1 24 25 34 200
2 300 12 45 11
3 34 19 2 34
4 75 76 19 11
5 42 89 29 101
6 54 104 11 12
Датафрейм df2:
E
0 25
1 12
2 104
3 12
Необходимо из датафрейма df1 удалить все строки, содержащие в столбце В элементы, которые встречаются в столбце Е датафрейма df2.
Мой код:
import pandas as pd
df1 = pd.DataFrame([[256, 4, 24, 51], [24, 25, 34, 200], [300, 12, 45, 11],
[34, 19, 2, 34], [75, 76, 19, 11], [42, 89, 29, 101], [54, 104, 11, 12]])
df1.rename({0: 'A', 1: 'B', 2: 'C', 3: 'D'}, axis=1, inplace=True)
df2 = pd.DataFrame([[25], [12], [104], [12]])
df2.rename({0: 'E'}, axis=1, inplace=True)
for row1 in df1.B:
for row2 in df2.E:
if row1 == row2:
df1.drop(row1)
print(df1)
выдает ошибку "KeyError: '[25] not found in axis'" Что не так?
Ответы (2 шт):
Не работайте с Pandas циклами, это очень неэффективно. Там есть все средства, чтобы делать всё "векторно", просто и красиво:
df1 = df1.loc[~df1.B.isin(df2.E)]
A B C D
0 256 4 24 51
3 34 19 2 34
4 75 76 19 11
5 42 89 29 101
~ - это отрицание
isin - функция, для проверки вхождения в Pandas.Series другой Series или списка.
Как обычно, в Pandas проще всё сделать с помощью фильтрации данных по условию, главное правильно составить условие.
А ошибка в вашем коде связана с тем, что вы перебираете значения из столбца, а функция drop по умолчанию считает, что ей передали индекс(ы) элементов, которые нужно удалить. И, конечно, в столбце B нет индекса 25 (а элемент есть).
ids = df2["E"]
res = df1.query("B not in @ids")
результат:
In [43]: res
Out[43]:
A B C D
0 256 4 24 51
3 34 19 2 34
4 75 76 19 11
5 42 89 29 101