Поиск нескольких строк в pandas без предопределения количества строк для использования

Мне интересно, есть ли более общий способ сделать ниже? Мне интересно, есть ли способ создать st-функцию, чтобы я мог искать не заданное количество строк?

Так, например, имея возможность создать обобщенную функцию st, а затем введите st ('Governor', 'Virginia', 'Google)

здесь моя текущая функция, но она предопределяет два слова, которые вы можете использовать. (df ​​является pandas DataFrame)

def search(word1, word2, word3 df):
    """
    allows you to search an intersection of three terms
    """
    return df[df.Name.str.contains(word1) & df.Name.str.contains(word2) & df.Name.str.contains(word3)]

st('Governor', 'Virginia', newauthdf)

Ответ 1

Вы можете использовать np.logical_and.reduce:

import pandas as pd
import numpy as np
def search(df, *words):  #1
    """
    Return a sub-DataFrame of those rows whose Name column match all the words.
    """
    return df[np.logical_and.reduce([df['Name'].str.contains(word) for word in words])]   # 2


df = pd.DataFrame({'Name':['Virginia Google Governor',
                           'Governor Virginia',
                           'Governor Virginia Google']})
print(search(df, 'Governor', 'Virginia', 'Google'))

печатает

                       Name
0  Virginia Google Governor
2  Governor Virginia Google

  • * в def search(df, *words) позволяет search принимать неограниченное количество позиционных аргументов. Он соберет все (после первого) и поместите их в список под названием words.
  • np.logical_and.reduce([X, Y, Z]) эквивалентно X & Y & Z. Это позволяет вам обрабатывать произвольно длинный список.

Ответ 2

str.contains может принимать регулярное выражение. поэтому вы можете использовать '|'.join(words) как шаблон; для безопасной карты на re.escape:

>>> df
                 Name
0                Test
1            Virginia
2              Google
3  Google in Virginia
4               Apple

[5 rows x 1 columns]
>>> words = ['Governor', 'Virginia', 'Google']

'|'.join(map(re.escape, words)) будет шаблон поиска:

>>> import re
>>> pat = '|'.join(map(re.escape, words))
>>> df.Name.str.contains(pat)
0    False
1     True
2     True
3     True
4    False
Name: Name, dtype: bool