Найдите строки фрейма данных, в которых указано c ячеек, которые соответствуют определенным c выражениям регулярного выражения - PullRequest
2 голосов
/ 04 мая 2020

Допустим, у меня есть Pandas фрейм данных:

data_df:

color          shape          number

green 5        triangle       3
green 1056     rectangle      2
blue           square         1
blue           circle         5
blue           square         4

, и у меня есть другой фрейм данных с этими параметрами фильтра:

filter_df:

color          shape          number

green .*       ANY            ANY
blue           square         1

Результат после фильтрации должен быть:

filtered_data_df:

color          shape          number

blue           circle         5
blue           square         4

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

color_regex = 'green .*|blue'
shape_regex = '.*|square'  # I would replace ANY with '.*'
number_regex = '.*|1'

После этого я бы просто использовал:

filtered_data_df = data_df.drop(
           data_df[data_df['color'].str.match(color_regex , case=False)].index &
           data_df[data_df['shape'].str.match(shape_regex , case=False)].index &
           data_df[data_df['number'].astype(str).str.match(number_regex, case=False)].index,
           axis=0)

но, конечно , поскольку у меня есть '. *' как в shape_regex, так и в number_regex, все будет отфильтровано, и я хочу, чтобы все было отфильтровано только для зеленого цвета, а для синего - только для комбинации blue / square / 1.

Я, вероятно, мог бы что-то написать, но для этого потребуется какой-то FOR l oop, который, работая с Pandas, я предполагаю, что могу пропустить использование.

В моем реальном случае data_dt может иметь до 5000 строк, а filter_dt может иметь ~ 100 строк (3 столбца) комбинаций параметров фильтрации с постоянным потенциалом дальнейшего роста (по строкам).

Мой вопрос в том, как справиться с этой фильтрацией в некоторых эффективных Pandas путь?

1 Ответ

0 голосов
/ 04 мая 2020

IIU C вы можете использовать понимание списка. Я должен отметить, что df - это ваш data_df, а df1 - это ваш filter_df

# replace any with .*
df1 = df1.replace('ANY', '.*')
# zip your columns
z = zip(df1['color'], df1['shape'], df1['number'])

# list comprehension with logic and str.contains
l = [~((df['color'].str.contains(c)) &\
       (df['shape'].str.contains(s)) & \
       (df['number'].astype(str).str.contains(n))).values for c,s,n in z]

# numpy.equal to see where the true values overlap then use boolean indexing
df[np.equal(*l)]

  color   shape  number
3  blue  circle       5
4  blue  square       4

вот пример данных

s = """color,shape,number
green 5,triangle,3
green 1056,rectangle,2
blue,square,1
blue,circle,5
blue,square,4"""

s1 = """color,shape,number
green .*,ANY,ANY
blue,square,1"""

df = pd.read_csv(StringIO(s))
df1 = pd.read_csv(StringIO(s1))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...