pandas преобразует запятую в тире внутри круглых скобок

#python #pandas

#python #pandas

Вопрос:

учитывая набор данных, который содержит запятые как часть текста, есть ли хороший / простой способ преобразовать их, чтобы я мог проанализировать остальные данные, используя «настоящие» запятые? запятые, которые я хочу игнорировать / переводить, всегда находятся внутри круглых скобок

 #Create Series
s = pd.Series(['one,two,ten','first,second,third(twenty,thirty,forty),last','ten,eleven,twelve'],['buz','bas','bur'])
k = pd.Series(['y','n','o'],['buz','bas','bur'])

#Create DataFrame df from two series
df = pd.DataFrame({'first':s,'second':k})

 

я думаю, что для каждой строки в столбце сначала мне нужно проверить наличие «(«, а затем, если есть «,» преобразовать его в «-«. затем, если я доберусь до «)», я останавливаю перевод.
В итоге у меня будет третий (двадцать-тридцать-сорок)

Существует ли синтаксический анализатор char by char, который может быть запущен с помощью «(»

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

 #Create Series
s = pd.Series(['one,two,ten','first,second,third(twenty-thirty-forty),last','ten,eleven,twelve'],['buz','bas','bur'])
k = pd.Series(['y','n','o'],['buz','bas','bur'])
df = pd.DataFrame({'first':s,'second':k})

 

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

1. пожалуйста, поделитесь примером ожидаемого результата

2. Я сделал. вместо третьего (двадцать, тридцать, сорок); мне нужно, чтобы он был третьим (двадцать-тридцать-сорок)

3. добавлено в оригинал для ясности

Ответ №1:

Давайте попробуем str.replace заменить лямбда-функцию

 repl = lambda g: g.group().replace(',', '-')
df['first'] = df['first'].str.replace(r'(.*?)', repl, regex=True)
 

Подробности регулярных выражений

  • ( : Соответствует символу (
  • .*? : Соответствует любому символу ноль или более раз, но как можно меньше раз (отложенное совпадение)
  • ) : Соответствует символу )

Смотрите online regex demo

Результат

 print(df)

                                            first second
buz                                   one,two,ten      y
bas  first,second,third(twenty-thirty-forty),last      n
bur                             ten,eleven,twelve      o
 

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

1. первый раз, когда я видел str.replace с вызываемым, очень приятно!

2. это работает! Спасибо. я понимаю большую часть этого, но немного запутался в r'((. *?))’ не могли бы вы разбить это для меня?

3. @kdot Я отредактировал ответ с объяснением регулярного выражения.

Ответ №2:

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

 def replace_comma(x):
    # create a list from the string
    x_list = [s for s in x]

    # create a second list to modify
    new_xlist = x_list

    # set a flag for when in paranthesis
    in_paranthesis = False

    # iterate through the list
    for count, character in enumerate(x_list):
        if character == '(':
            in_paranthesis = True
        elif character == ')':
            in_paranthesis = False
        elif character == ',' and in_paranthesis is True:
            # if in paranthesis, replace comma with '/'
            new_xlist[count] = '/'

    # return new_xlist, with /'s, joined as a string
    return ('').join(new_xlist)
 

Использование pandas применяется к каждому столбцу:

 df = df['first'].apply(replace_comma)
 

Ответ №3:

Использование str.replace и регулярное выражение.

 df['first'].str.replace(r"(,(?=[^()]*)))", '-')
 

 Output:
buz                                     one,two,ten
bas    first,second,third(twenty-thirty-forty),last
bur                               ten,eleven,twelve
Name: first, dtype: object