Как извлечь строки до и после пробела, специальные символы? - PullRequest
0 голосов
/ 28 мая 2019

У меня есть фрейм данных "trial_df" со значениями столбца ниже, как показано ниже:

Names

GHAITHA & AL MOOSA
ASEEL ELECTRONICS T
SUNRISE SUPERMARKET-QU
EMARAT-AL SAFIYAH(6735
LULU CENTRE LLC EFT TE
MAX
THEMAX
THE LULU
GHAITHA 123
SUNRISE %$#

Требование:

1) Извлечение только строк до и после пробела, специальных символов.

Например, например: "ASEEL ELECTRONICS T" станет "ASEEL ELECTRONICS

2) Но только при следующих условиях:

a) длина второй строки должна быть больше, чем 2

b) вторая строка должна быть буквенно-цифровой

Например: 'GHAITHA & AL MOOSA' будет просто 'GHAITHA', поскольку вторая строка после пробела - '&' (оба условия не выполняются: не алфавитно-цифровая идлина не превышает 2)

Например: «MAX» будет «MAX» как его единственная строка, так же как «LULU» будет таким же, как уже две строки.

Окончательный результат:

Names

GHAITHA
ASEEL ELECTRONICS
SUNRISE SUPERMARKET-QU
EMARAT
LULU CENTRE
MAX
THEMAX
THE LULU
GHAITHA
SUNRISE

Моя функция выполнить требование:

def remove_strings(df, col):
    for i in df.index:
        x = df.at[i, col]
        x = x.split(' ')
        if len(x) > 1:
            if len(x[1]) > 2:
                x[1] = ''.join(e for e in x[1] if e.isalnum())
                x = ' '.join(x[0:2])
                df.at[i, col] = x
            else:
                df.at[i, col] = x[0]
        else:
            df.at[i, col] = df.at[i, col]

#calling my function 
remove_strings(df=trial_df, col='Names')

Проблема с моей функцией: хотя она решает требование, но не оптимизирована. Мои данные болеечем 1 миллион строк, так что это циклы, которые много разich очень много времени.Есть ли очень хороший оптимизированный способ решить мое требование?

Ответы [ 2 ]

0 голосов
/ 28 мая 2019
 df.Names.replace(regex=r'^(\w+)(\s[A-Z-]{2,})?.*',value=r'\1\2')
Out[186]: 
0                   GHAITHA
1         ASEEL ELECTRONICS
2    SUNRISE SUPERMARKET-QU
3                    EMARAT
4               LULU CENTRE
5                       MAX
6                    THEMAX
7                  THE LULU
8                   GHAITHA
9                   SUNRISE
Name: Names, dtype: object
0 голосов
/ 28 мая 2019

Выражение, которое мы хотели бы разработать здесь, довольно сложное. Возможно, было бы лучше разбить задачу, тогда мы бы разработали гораздо более простые выражения. Например, случай THE LULU может быть просто исключен, прежде чем мы запустим его через механизм регулярных выражений.

Моя частичная попытка выражения:

^([A-Z\s]{3,}?)(&.+|\s[A-Z]{1}$|-.+|\s[A-Z]{3}\s.+|\s[0-9].+|\s[~!@#$%^&*]+.+)$

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

DEMO


Идея состоит из трех шагов:

  • Мы берем те, которые просто найти / отфильтровать, например, "THE LULU"
  • Мы добавляем группу захвата с наибольшим количеством границ ^([A-Z\s]{3,}?)
  • Мы добавляем еще одну группу с подвыражениями, связанными с логическими ИЛИ, и отфильтровываем то, что мы хотим быть в конце нашей строки.

enter image description here

...