Замените строковые значения столбца, если они содержатся в скобках - PullRequest
3 голосов
/ 13 апреля 2020

В качестве примера у меня есть следующий фрейм данных:

test = pd.DataFrame({'type':['fruit-of the-loom (sometimes-never)', 'yes', 'ok (not-possible) I will try', 'vegetable', 'poultry', 'poultry'],
                 'item':['apple', 'orange', 'spinach', 'potato', 'chicken', 'turkey']})

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

У кого-нибудь есть предложение о том, как мне этого добиться?

split позаботится о дефисе если он был ведущим и rsplit, если он тянулся. Я не могу придумать способ решить эту проблему.

, в этом случае идеальным результатом для значений в этом гипотетическом столбце будет:

'fruit-of the-loom (sometimes never)',
'yes', 
'ok (not possible) I will try', 
'vegetable', 
'poultry', 
'poultry'`

Ответы [ 3 ]

2 голосов
/ 13 апреля 2020

Одним из способов может быть использование str.replace с шаблоном, ищущим, что находится между круглыми скобками, и параметр замены может быть лямбда-выражением, использующим replace для соответствующего объекта:

print (test['type'].str.replace(pat='\((.*?)\)', 
                                repl=lambda x: x.group(0).replace('-',' ')))
0    fruit-of the-loom (sometimes never)
1                                    yes
2           ok (not possible) I will try
3                              vegetable
4                                poultry
5                                poultry
Name: type, dtype: object

Объяснение того, что в pat= можно найти здесь

1 голос
/ 13 апреля 2020
test.type = (test.type.str.extract('(.*?\(.*?)-(.*?\))(.*)')
             .sum(1)
             .combine_first(test.type))

Объяснение:

  • Извлечение групп регулярных выражений beginning until parenthesis and then hyphen и after hyphen until parenthesis and then optional additional stuff
  • Снова объедините их вместе с помощью sum
  • Где, NaN, используйте значения из оригинала (combine_first)

Таким образом, дефис удаляется, а не заменяется пробелом. Если вам нужен пробел, вы можете использовать apply вместо суммы:

test.type = (test.type.str.extract('(.*?\(.*?)-(.*?\))(.*)')
             .apply(lambda row: ' '.join(row.values.astype(str)), axis=1)
             .combine_first(test.type))

В любом случае, это не сработает для более чем одного набора скобок.

0 голосов
/ 13 апреля 2020

Мне следовало подумать об этом немного дольше.

Это решение, которое я придумал, "

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

def inside_parens(string):
    parens_count = 0
    return_string = ""
    for a in string:
        if a == "(":
            parens_count += 1
        elif a == ")":
            parens_count -= 1
        if parens_count > 0:
            return_string += a.replace('-', ' ')
        else:
            return_string += a
    return return_string


    return return_string

Как только это будет сделано, примените его к намеченному столбцу:

df['col_1'] = df['col_1'].apply(inside_parens)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...