Панды несколько строк поиска - PullRequest
0 голосов
/ 13 июня 2018

Я работаю над сценарием для чтения и обработки данных из файлов Excel, и мне нужно отфильтровать строки, содержащие несколько строк.

В настоящее время метод фильтрации жестко задан для каждого типа листа Excel (каждыйТип листа получает один дочерний класс, который наследуется от родительского, который имеет дело с чтением файла и первой обработкой), который я читаю, но так как это становится очень утомительным, так как число листов, которые я должен проанализировать, растет, я ищуболее элегантное решение.

Прямо сейчас я реализовал его так:

def _find(self,find_str,column='Data1'):
    return (self.df[column].str.find(find_str) > -1)
def filter(self):
    self.df_filter = self.df[(self._find('This') | self._find('is')) 
                           & self._find('an') | self._find('example')]

с переопределенным методом фильтра для каждого дочернего класса.Иногда логические (на самом деле двоичные) выражения могут быть очень длинными.

Есть ли согласованный, читаемый способ сократить это?Я думал о чем-то вроде передачи объекта, похожего на логическое выражение, в обобщенную функцию фильтра, например

gen_find(('This' | 'is') & 'an' | 'example')

(я знаю, что это точно будет плохой идеей, но вы понимаете, в чем суть)

1 Ответ

0 голосов
/ 13 июня 2018

pd.Series.str.find(x) > -1 эквивалентно pd.Series.str.contains(x).Оба дают логические ряды, которые вы можете использовать для фильтрации вашего фрейма данных.Один из способов упростить вашу логику - использовать регулярное выражение с pd.Series.str.contains.

Например, определите список подстрок, которые вы хотите найти:

L = ['This', 'is', 'an', 'example']

Затем объедините их в выражении регулярного выражения.,Если у вас есть символы, которые нужно экранировать, используйте re.escape:

import re
regexp = '|'.join([re.escape(i) for i in L])

Наконец, включите это выражение в маску серии:

df = df[df['col'].str.contains(regexp)]

Вы можете комбинировать несколько or условийс оператором &:

mask1 = df['col'].str.contains(regexp1)
mask2 = df['col'].str.contains(regexp2)

df = df[mask1 & mask2]
...