Поиск пересечения между списком строк столбца pandas и вторым списком строк

avatar
Garglesoap
8 августа 2021 в 18:20
716
3
1

У меня есть pandas df со столбцом списков слов, например:

df = pd.DataFrame({'Text':[['cat','dog','mouse'], ['horse','dog','rabbit'], ['cow','pig','hawk']] })

и второй df со списком слов для соответствия, например:

df2 = pd.DataFrame({'FarmAnimals':['horse','cow','pig'] })

И я хочу получить новый столбец с пересечением df и df2, например:

df3 = pd.DataFrame({'Text':[['cat','dog','mouse'], ['horse','dog','rabbit'], ['cow','pig','hawk'], 'Intersect':[],['horse'],['cow', 'pig'] })

Это мой текущий код, но на данный момент я практически все перепробовал

def match(df):

    def find_match(v):
        inter = set(v).intersection(list(df2['FarmAnimals']))
        return inter

    df['Intersect'] = df['Text'].apply(find_match)
    df = df[['Intersect']]
    return df

Но он продолжает преобразовывать v в список символов, а затем возвращает совпадения из одного символа. Я, вероятно, потратил более 20 часов на эту единственную ошибку и прошел через нее. Пересечение нескольких столбцов Pandas Поиск пересечения двух рядов в Pandas с использованием индекса Как я могу получить пересечение двух текстовых столбцов серии панд? и т. д. и т. д. и т. д., но ни один из них не был отдаленно полезен. В качестве дополнительного примечания: df имеет массивный размер (1 mil строк), а df2 также является Massice (100 000 строк), а fxn выполняется через ray python (оболочка стрелок apache).

Редактировать: это может быть ошибка типа данных, выходные данные, поступающие в пересечение, применяются ниже:

print(df.dtypes)
print(type(df['Text']))
print(df2.dtypes)
print(type(df2['FarmAnimals']))
print(type(df.iloc[0,0]))
print(df.iloc[0,0]))
print(type(df2.iloc[0,0]))

dtype: object
<class 'pandas.core.series.Series'>
dtype: object
<class 'pandas.core.series.Series'>
<class 'str'>
['cat', 'rat', 'rabbit']
<class 'str'>

Разве класс ячеек df['Text'] не должен быть списком??

Решено: проблема с pd.read_csv, преобразующим столбец списка в строку. Обработан столбец сразу после чтения csv с помощью:

from ast import literal_eval
text_data.raw_text = text_data.raw_text.apply(literal_eval)
Источник
MDR
8 августа 2021 в 18:28
0

Возможно: Добавить идентификатор, найденный в списке, в новый столбец в кадре данных pandas. Возможно, поменяйте список bad_ids на df2['FarmAnimals']

mozway
8 августа 2021 в 18:59
0

Вы можете напечатать df2['FarmAnimals'].iloc[0]?

Garglesoap
8 августа 2021 в 19:06
0

просто добавил несколько из этих выходов

Ответы (3)

avatar
SeaBean
8 августа 2021 в 19:49
1

Используйте функцию numpy numpy.intersect1d(), чтобы найти пересечение для более быстрого выполнения (особенно при большом наборе данных):

import numpy as np

df['Intersect'] = df['Text'].map(lambda x: np.intersect1d(x, df2['FarmAnimals'].values))

Здесь для каждого списка строк в столбце text мы используем numpy.intersect1d(), чтобы найти пересечение между списком и значениями столбца столбца FarmAnimals.<3969774>7383

Результат:

print(df)

                   Text   Intersect
0     [cat, dog, mouse]          []
1  [horse, dog, rabbit]     [horse]
2      [cow, pig, hawk]  [cow, pig]

avatar
anky
8 августа 2021 в 18:37
0

Другой способ с series.str.findall:

import re
p = r'\b(?:{})\b'.format('|'.join(map(re.escape, df2['FarmAnimals'])))
df['Intersect'] = df['Text'].astype(str).str.findall("("+p+")")

print(df)

                   Text   Intersect
0     [cat, dog, mouse]          []
1  [horse, dog, rabbit]     [horse]
2      [cow, pig, hawk]  [cow, pig]
avatar
mozway
8 августа 2021 в 18:26
2

Вы можете использовать pandas.Series.apply и наборы:

df['Intersect'] = (df['Text']
                     .apply(lambda x: list(set(x).intersection(set(df2['FarmAnimals'])))
                           )
                  )

выход:

                   Text   Intersect
0     [cat, dog, mouse]          []
1  [horse, dog, rabbit]     [horse]
2      [cow, pig, hawk]  [cow, pig]
mozway
8 августа 2021 в 18:32
0

Я понимаю, что на самом деле это очень похоже на то, что вы сделали… Вы уверены, что код не работает?

Garglesoap
8 августа 2021 в 18:53
1

это производит тот же вывод отдельных символов. У меня может быть ошибка типа данных, вопрос об обновлении...