Поиск строк с заглавными буквами, заканчивающихся определенным словом в регулярном выражении

#python #regex #pandas #extract

#python #регулярное выражение #pandas #извлечь

Вопрос:

У меня есть фрейм данных, где один столбец состоит из строк, имеющих три шаблона:

1) Только прописные буквы: APPLE COMPANY

2) Буквы верхнего регистра и заканчивающиеся буквами В ВИДЕ: CAR COMPANY AS

3) Буквы верхнего и нижнего регистра: John Smith

 df = pd.DataFrame({'NAME': ['APPLE COMPANY', 'CAR COMPANY AS', 'John Smith']})

             NAME ...
0   APPLE COMPANY ...
1  CAR COMPANY AS ...
2      John Smith ...
3             ... ...
  

Как я могу удалить те строки, которые не соответствуют условиям 2) и 3), т.е. 1)? Другими словами, как я могу удалить строки, которые содержат только заглавные буквы, не заканчиваются на AS или содержат как ВЕРХНИЕ, так и НИЖНИЕ буквы в строке?

Я придумал это:

 df['NAME'].str.findall(r"(^[A-Z ':] $)")
df['NAME'].str.findall('AS')
  

Первый извлекает строки только с заглавными буквами, а второй только находит AS . Если есть другие методы, отличные от регулярных выражений, я с удовольствием попробую и это.

Ожидаемый результат:

              NAME ...
1  CAR COMPANY AS ...
2      John Smith ...
3             ... ...
  

Ответ №1:

Это регулярное выражение должно работать:

 ^(?:[A-Z ':]  AS|.*[a-z].*)$
  

Это соответствует любому из этих:

  • [A-Z ':] AS — Регистр всех заглавных букв, за которыми следует AS
  • .*[a-z].* — Регистр строчных букв

ДЕМОНСТРАЦИЯ

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

1. Ваш ответ лучший :), для решения на основе pandas df['NAME'] = df['NAME'].str.extract("(^(?:[A-Z ':] AS|.*[a-z].*)$)")

Ответ №2:

одним из способов было бы,

 df['temp']=df['NAME'].str.extract("(^[A-Z ':] $)")
s1=df['temp']==df["NAME"]
s2=~df['NAME'].str.endswith('AS')

print(df.loc[~(s1amp;s2), 'NAME'])
  

O/P:

 1    CAR COMPANY AS
2        John Smith
Name: NAME, dtype: object
  

Ответ №3:

Также вы можете попробовать:

 df_new = df[~df['NAME'].str.isupper()|df['NAME'].str.endswith('AS')]
  

Ответ №4:

Использование apply и других шаблонов, которые вы можете захотеть проверить:

 import re
def myfilter(x):
    patterns = ['[A-Z]*AS$','[A-Z][a-z]{1,}']
    for p in patterns:
        if len(re.findall(p, x.NAME)):
            return True
    return False

selector = df.apply(myfilter, axis=1)

filtered_df = df[selector]