Удалите все знаки препинания из кадра данных, кроме некоторых символов

Я пытаюсь удалить все знаки пунктуации с кадра данных, кроме символов "<" и ">"

Я старался:

def non_punct(df):

    df['C'] = df['C'].str.replace('[^\w\s]' | ~(<) | ~(>),' ')

    return df

Выход:

    File "<ipython-input-292-ac8369672f62>", line 3
        df['Description'] = df['Description'].str.replace('[^\w\s]' | ~(<) | ~(>),' ')
                                                                ^
SyntaxError: invalid syntax

Мой фрейм данных:

       A          B                                    C
  French      house               Phone. <phone_numbers>
 English      house               email - <adresse_mail>
  French  apartment                      my name is Liam
  French      house                        Hello George!
 English  apartment   Ethan, my phone is <phone_numbers>

Хороший выход:

       A          B                                    C
  French      house               Phone <phone_numbers>
 English      house               email  <adresse_mail>
  French  apartment                     my name is Liam
  French      house                        Hello George 
 English  apartment   Ethan my phone is <phone_numbers>

3 ответа

Решение

Вот способ с string.punctuation:

>>> import re
>>> import string

>>> import pandas as pd

>>> df = pd.DataFrame({
...     'a': ['abc', 'de.$&$*f(@)<', '<g>hij<k>'],
...     'b': [1234, 5678, 91011],
...     'c': ['me <me@gmail.com>', '123 West-End Lane', '<<xyz>>']
... })

>>> punc = string.punctuation.replace('<', '').replace('>', '')

>>> pat = re.compile(f'[{punc}]')
>>> df.replace(pat, '')
           a      b                 c
0        abc   1234   me <megmailcom>
1       def<   5678  123 WestEnd Lane
2  <g>hij<k>  91011           <<xyz>>

Вы должны еще раз проверить, что эта константа включает то, что вы хотите:

Строка символов ASCII, которые считаются знаками препинания в языке C.

Ценности:

>>> string.punctuation
'!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
>>> string.punctuation.replace('<', '').replace('>', '')
'!"#$%&\'()*+,-./:;=?@[\\]^_`{|}~'

Заметки:

  • Это решение использует f-строку (Python 3.6+)
  • Он включает в себя эти буквенные символы в наборе символов, чтобы соответствовать любому из них
  • Обратите внимание на разницу между df.replace() а также df[my_column_name].str.replace(), Подпись для pd.DataFrame.replace() является DataFrame.replace(to_replace=None, value=None, inplace=False, limit=None, regex=False, method='pad'), где to_replace может быть регулярным выражением

Вот способ достичь вашего результата с re.sub, Кроме того, я думаю, что ваше регулярное выражение выключено, должно быть [[^\w\s^<^>]|_, Это соответствует всему, что не является числом, целым числом, пробелом, <или>. Вы должны явно соответствовать подчеркиванию, потому что это освобождается в \w,

import re
re.sub('[^\w\s^<^>]|_', ' ', 'asdf.,:;/\><a b_?!"§$%&a')
>>> 'asdf      ><a b        a'

Просто для сравнения:

re.sub('[^\w\s] | ~(<) | ~(>)', ' ', 'asdf.,:;/\><a b_?!"§$%&a')
>>> 'asdf.,:;/\\><a b_?!"§$%&a'

re.sub('[^\w\s^<^>]', ' ', 'asdf.,:;/\><a b_?!"§$%&a')
>>> 'asdf      ><a b_       a'

РЕДАКТИРОВАТЬ: Ваша ошибка возникает из-за неуместной кавычки: она должна быть '[^\w\s] | ~(<) | ~(>)' и не '[^\w\s]' | ~(<) | ~(>)

РЕДАКТИРОВАТЬ 2: как указано @Brad Solomon, pd.Series.str.replace отлично работает с регулярным выражением, поэтому добавление [[^\w\s^<^>]|_ как образец, чтобы соответствовать в вашем утверждении, должен добиться цели. Хотя не проверял это. @marin: Если вы попробуете это, оставьте мне отзыв, чтобы я мог обновить пост, если это необходимо.

В одну строку (кроме import) это было бы:

import string
df['C'] = df['C'].str.translate(None, string.translate(string.punctuation, None, '<>'))
Другие вопросы по тегам