Проверьте, содержит ли серия какой-либо элемент из списка

#python #pandas #numpy

Вопрос:

Я читаю большой CSV-файл, и один из столбцов представлен ниже.

 import pandas as pd

df['col1'] = pd.Series(
    ["37", "AWESOME House", "Yellow Cottage, 107", "14"], dtype='object'
)
 

Мой код использует «векторизованные строковые методы» для своевременного возврата требуемых данных.

Упрощенный код для иллюстрации некоторых частей логики.

 import numpy as np

sth = np.where(
    <check condition>,
    df['col1'].str.lower(),
    df['some_other_column'].whatever()
)
 

Затем я хотел бы проверить, содержит ли каждое значение в моем Series списке какой-либо элемент из списка ниже.

 check_list = ['a', 'b', 'c']
 

Таким образом, ожидаемый результат (для «условия проверки») будет:

 False
True
True
False
 

Я попробовал это

 np.where(
    np.any([x in df['col1'].str.lower() for x in check_list])
...
 

но получена ошибка:

 ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
 

Как я мог бы правильно решить свою проблему?

Ответ №1:

Используйте Series.str.contains со связанными значениями списка по | для регулярного or выражения с case=False для поиска без учета регистра:

 print (df['col1'].str.contains('|'.join(check_list), case=False))
0    False
1     True
2     True
3    False
Name: col1, dtype: bool
 

Без regex :

 print (df['col1'].apply(lambda x: any([i in x.lower() for i in check_list])))
0    False
1     True
2     True
3    False
Name: col1, dtype: bool
 

 print ([any([i in x.lower() for i in check_list]) for x in df['col1']])
[False, True, True, False]
 

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

1. Это работает — спасибо! Однако он использует регулярные выражения, поэтому он замедлил генерацию моих данных примерно на 10% (судя по первоначальным тестам). Как бы вы решили эту проблему без регулярных выражений ?

2. Я думал apply , что метод будет медленным, поскольку, насколько я понимаю, он возвращает новый фрейм данных/серию, которые мне на самом деле не нужны…. В любом случае, я сравнил apply с map пониманием списка и Python ( [any(...) for x in df['col']] ) и apply это самый быстрый! Любое дальнейшее повышение производительности приветствуется 🙂