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

#python #pandas #dataframe

#python #pandas #фрейм данных

Вопрос:

Я борюсь со следующей проблемой:

Допустим, у меня есть следующий входной фрейм данных:

 df
something library                                                     other_info
FOO       NaN                                                         blaa      
BAR       ['bar/libBAR.a', 'bar/libBAR.cpp.so', 'bar/libBARFIGHT.so'] bluu          
MEH       ['meh/libMEH.a', 'meh/libMEH.so', 'meh/libMEH.other.so']    blqq      
 

Затем, используя explode функциональность фрейма данных:

 df1 = df.explode('library')

something library             other_info
FOO       NaN                 blaa      
BAR       bar/libBAR.a        bluu     
BAR       bar/libBAR.cpp.so   bluu      
BAR       bar/libBARFIGHT.so  bluu      
MEH       meh/libMEH.a        blqq      
MEH       meh/libMEH.so       blqq
MEH       meh/libMEH.other.so blqq
 

После этого я применяю фильтрацию с помощью регулярного выражения для создания фрейма данных подмножества:

 regex = '.*/lib.*.a'
df2 = df1[df1.library.str.contains(regex, regex=True, na=False)]

something library      other_info
BAR       bar/libBAR.a bluu
MEH       meh/libMEH.a blqq
 

Итак, теперь я пытаюсь удалить записи, которые я отфильтровал из df1, используя «условие»:

создание условия (серия True / False)

 condition = df1['library']isin(df2['library'])

something 
FOO       False
BAR       True
BAR       False
BAR       False
MEH       True
MEH       False
MEH       False
 

При этом условии я пытаюсь удалить нужные записи из d1 (без создания нового фрейма данных):

 d1.drop(d1[condition].index, inplace=True)
 

Результат, однако, довольно неожиданный:

 something library             other_info
FOO       NaN                 blaa  
 

Итак, все записи для BAR и MEH были удалены из фрейма данных, хотя только одна строка на «что-то» соответствует.

Что я делаю не так? Каков правильный способ фильтрации только «истинных» строк и можно ли это сделать с использованием метода «filter»?

Ответ №1:

Вы можете просто фильтровать not condition следующим образом

 df3 = df1[~condition]
df3
 

производит

 
    something   library             other_info
0   FOO         NaN                 blaa
1   BAR         bar/libBAR.cpp.so   bluu
1   BAR         bar/libBARFIGHT.so  bluu
2   MEH         meh/libMEH.so       blqq
2   MEH         meh/libMEH.other.so blqq
 

это работает для вас?

Ваш исходный код будет работать, если вы обновите свое explode утверждение следующим образом:

 df1 = df.explode('library', ignore_index = True)
 

который переиндексирует фрейм данных, что означает, что ваши последующие манипуляции используют уникальные значения индекса, а не исходные (которые повторяются для строк, которые были разнесены из одной и той же строки)

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

1. df1[~условие] работает так, как ожидалось. Спасибо! Для вашего другого предложения: в будущем мне придется объединить строки (отменить функцию разнесения). если я использую ignore_index = True , разве это не усложнит задачу?

2. если значения в столбце «что-то» изначально уникальны, то вы всегда можете groupby использовать этот столбец после всех этих манипуляций. если нет, и для этого вам нужно полагаться на исходный индекс, то да, это было бы сложнее сделать, если вы сбросите его. Итак, если df [~ condition]` работает для вас, я бы придерживался этого

3. Да, значения в «что-то» уникальны до .expode() , с чем я буду играть groupby . Спасибо!