Как отфильтровать значения Pandas Dataframe, которые содержат строки в списке? - PullRequest
2 голосов
/ 01 мая 2019

У меня есть фрейм данных с такими значениями:

  A                    B
"I need avocado"   "something"
"something"      "I eat margarina"

И я хочу найти строки, которые соответствуют:

В любом столбце строки, его значение содержится в списке. например:

["apple","avocado","bannana"]

И только эта строка должна соответствовать: "Мне нужен авокадо"

Эта строка не работает:

dataFiltered[dataFiltered[col].str.contains(*includeKeywords)]

Возвращает:

{TypeError}unsupported operand type(s) for &: 'str' and 'int'

Что мне делать?

Ответы [ 2 ]

2 голосов
/ 01 мая 2019

Настройка

df = pd.DataFrame(dict(
    A=['I need avocado', 'something', 'useless', 'nothing'],
    B=['something', 'I eat margarina', 'eat apple', 'more nothing']
))
includeKeywords = ["apple", "avocado", "bannana"]

Проблема

                A                B
0  I need avocado        something  # True 'avocado' in A
1       something  I eat margarina
2         useless        eat apple  # True 'apple' in B
3         nothing     more nothing

Решение

  • pandas.DataFrame.stack, чтобы сделать df a Series и позволить нам использовать pandas.Series.str функции доступа
  • pandas.Series.str.contains с '|'.join(includeKeywords)
  • pandas.Series.any с аргументом level=0, потому что мы добавили уровень в индекс, когда мы сложили

df[df.stack().str.contains('|'.join(includeKeywords)).any(level=0)]

                A          B
0  I need avocado  something
2         useless  eat apple

Подробнее

Это создает строку поиска regex. В regex, '|' означает or. Таким образом, для поиска regex это означает, что соответствует 'apple', 'avocado' или 'bannana'

kwstr = '|'.join(includeKeywords)
print(kwstr)

apple|avocado|bannana

Укладка сгладит нашу DataFrame

df.stack()

0  A     I need avocado
   B          something
1  A          something
   B    I eat margarina
2  A            useless
   B          eat apple
3  A            nothing
   B       more nothing
dtype: object

К счастью, метод pandas.Series.str.contains может обрабатывать regex, и он будет выдавать логическое значение Series

df.stack().str.contains(kwstr)

0  A     True
   B    False
1  A    False
   B    False
2  A    False
   B     True
3  A    False
   B    False
dtype: bool

В этот момент мы можем хитро использовать pandas.Series.any, предлагая заботиться только о level=0

mask = df.stack().str.contains(kwstr).any(level=0)
mask

0     True
1    False
2     True
3    False
dtype: bool

Используя level=0, мы сохранили исходный индекс в результирующем Series. Это делает его идеальным для фильтрации df

df[mask]

                A          B
0  I need avocado  something
2         useless  eat apple
2 голосов
/ 01 мая 2019

Воспользуйтесь функцией any() и используйте список со списком в df.apply()

df = pd.DataFrame(["I need avocado","I eat margarina"])
print(df)
#                  0
# 0   I need avocado
# 1  I eat margarina

includeKeywords = ["apple","avocado","bannana"]

print(df[df.apply(lambda r: any([kw in r[0] for kw in includeKeywords]), axis=1)])
#                 0
# 0  I need avocado

Чтобы сделать это немного понятнее, вам в основном нужно создать маску, которая возвращает True / False длякаждая строка

mask = [any([kw in r for kw in includeKeywords]) for r in df[0]]
print(mask)

Затем вы можете использовать эту маску для печати выбранных строк в вашем DataFrame

# [True, False]
print(df[mask])
#                 0
# 0  I need avocado

Я показываю вам оба способа, потому что метод df.apply() удобен дляодин вкладыш, это действительно медленно по сравнению со стандартным пониманием списка.Так что если у вас достаточно маленький набор, не стесняйтесь использовать df.apply().В противном случае, я бы предложил понимание Python по методу панд.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...