Скажем, у меня есть 2 столбца списка, как показано ниже:
group1 = [['John', 'Mark'], ['Ben', 'Johnny'], ['Sarah', 'Daniel']]
group2 = [['Aya', 'Boa'], ['Mab', 'Johnny'], ['Sarah', 'Peter']]
df = pd.DataFrame({'group1':group1, 'group2':group2})
Я хочу сравнить два столбца списка и удалить элементы списка из group1, если они присутствуют в group2. Итак, ожидаемые результаты для вышеуказанного:
group1 group2
['John', 'Mark'] ['Aya', 'Boa']
['Ben'] ['Mab', 'Johnny']
['Daniel'] ['Sarah', 'Peter']
Как я могу это сделать? Я пробовал это:
df['group1'] = [[name for name in df['group1'] if name not in df['group2']]]
Но получил ошибку:
TypeError: unhashable type: 'list'
Пожалуйста помоги.
Вам нужно застегнуть две серии. Я использую набор здесь для эффективности (это не критично, если у вас всего несколько элементов в списке):
df['group1'] = [[x for x in a if x not in S]
for a, S in zip(df['group1'], df['group2'].apply(set))]
Вывод:
group1 group2
0 [John, Mark] [Aya, Boa]
1 [Ben] [Mab, Johnny]
2 [Daniel] [Sarah, Peter]
Вы можете использовать цикл в лямбда-функции:
df['group1']=df[['group1','group2']].apply(lambda x: [i for i in x['group1'] if i not in x['group2']],axis=1)
print(df)
'''
group1 group2
0 [John, Mark] [Aya, Boa]
1 [Ben] [Mab, Johnny]
2 [Daniel] [Sarah, Peter]
'''
Ты прав. Думаю, мне нужно больше работать над эффективностью. Спасибо.
Вы можете использовать установленную разницу:
df.apply(lambda x: set(x['group1']).difference(x['group2']), axis=1)
Вывод:
0 {John, Mark}
1 {Ben}
2 {Daniel}
dtype: object
Чтобы получить списки, вы можете добавить .apply(list) в конце.
Обратите внимание, что это менее эффективно, чем использование понимания списка и набора;)