Сравните два столбца, которые содержат списки слов в фрейме данных Pandas

#python #pandas #list

Вопрос:

Я пытаюсь найти слова, которые не являются общими между двумя столбцами pandas, содержащими списки.

Слова не всегда расположены в одном и том же порядке, и длина списка может варьироваться.

В качестве примера

 column1            column2
['a','b']          ['c','a','b']
['c','a']          ['a','b','d','c']
 

результат, которого я хочу, это

 column3
['c']
['b','d']
 

Заранее благодарю вас!

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

1. Оба решения дают пустой список в первой строке, когда мы меняем местами 2 элемента из 2 столбцов в первой строке.

2. Поскольку от 2 поставщиков решений нет ответа, я опубликовал новое решение, предназначенное для этого случая column1 , — это надмножество column2 использования symmetric_difference() , а не просто difference() .

Ответ №1:

Поскольку ваша цель-искать слова, которые не являются общими для 2 столбцов pandas, я полагаю, вы также хотите найти необычные элементы, когда column1 список элементов является надмножеством column2 списка, и наоборот.

К сожалению, 2 существующих решения не подходят для этого случая, например

      column1       column2
0  [c, a, b]        [a, b]
1     [c, a]  [a, b, d, c]
 

Оба других решения дают результат в column3 виде:

      column1       column2 column3
0  [c, a, b]        [a, b]      []             <==  empty list [] instead of ['c']
1     [c, a]  [a, b, d, c]  [b, d]
 

Если вы хотите, чтобы результат отображался выше ['c'] , а [] не для первой строки, вы можете сделать это следующим образом:

symmetric_difference() Вместо этого используйте функцию:

 df['column3'] = df.apply(lambda x: list(set(x['column1']).symmetric_difference(set(x['column2']))), axis=1)
 

Результат:

 print(df)

     column1       column2 column3
0  [c, a, b]        [a, b]     [c]
1     [c, a]  [a, b, d, c]  [b, d]
 

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

1. Ты прав.. на самом деле это лучше всего работает в данном случае. Я отметил этот ответ как правильный. Спасибо!

2. @Sarin Добро пожаловать! Всегда не так просто собрать хорошие данные для тестирования, чтобы полностью протестировать решение. Но не забудьте включить хорошее сочетание различных случаев (как в этом случае, некоторые с более длинным столбцом 1, а некоторые с более длинным столбцом 2), чтобы также получить полное решение! 🙂 Счастливого программирования и хорошего дня! 🙂

Ответ №2:

Попробуйте это, используя set разницу:

 >>> df['column3'] = df.applymap(set).diff(axis=1).dropna(axis=1).squeeze().map(list)
>>> df
  column1       column2 column3
0  [a, b]     [c, a, b]     [c]
1  [c, a]  [a, b, d, c]  [b, d]
>>> 
 

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

1. @SaraMichetti Ваше приветствие, пожалуйста, примите, если это поможет, нажав на галочку 🙂

2. Это не работает, если элемент in column1 является надмножеством соответствующего элемента column2 в той же строке. Попробуйте поменять местами 2 элемента в первой строке и проверьте результат.

Ответ №3:

Мы можем достичь ожидаемого результата , преобразовав lists in sets , затем применив a diff и повторно преобразовав результат в list :

 >>> df.applymap(set).diff(axis=1).dropna(axis=1).applymap(list)
    column2
0   [c]
1   [b, d]
 

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

1. Рад помочь 🙂 !