Отделите строку от числа в одном столбце Pandas Dataframe и создайте два новых столбца - PullRequest
3 голосов
/ 19 июня 2019

Я шокирован, что никто не спрашивал об этом раньше на SO ... поскольку это кажется достаточно простой проблемой.

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

df = pd.DataFrame(data=[['APPLEGATE WINERY    455.292049'],['AMAND FARM  849.827192'],['COBB FARM ST    1039.49357'],['DIRIGIA 2048.947284']], columns = ['Col1'])

    Col1
0   APPLEGATE WINERY 455.292049
1   AMAND FARM 849.827192
2   COBB FARM ST 1039.49357
3   DIRIGIA 2048.947284

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

Name                Area
APPLEGATE WINERY    455.292049
AMAND FARM          849.827192
COBB FARM ST        1039.49357
DIRIGIA             2048.947284

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

Таким образом, один результат будет выглядеть следующим образом:

df['Name'] = df.Col1.str.extract('([A-Z]\w{0,})', expand=True)
df['Area'] = df.Col1.str.extract('(\d)', expand=True)

Но есть ли хорошее, чистое решение, позволяющее решить эту проблему без необходимости использовать RegEx и вместо этого разделять строки из чисел на два столбца?

Ответы [ 4 ]

6 голосов
/ 19 июня 2019

Используйте один вызов extract.Вы также захотите удалить конечные пробелы из результата, если вы используете это регулярное выражение.

df2 = (df['Col1'].str.extract(r'(?P<Name>.*?)(?P<Area>\d+(?:\.\d+)?)')
                 .applymap(str.strip))
df2
               Name         Area
0  APPLEGATE WINERY   455.292049
1        AMAND FARM   849.827192
2      COBB FARM ST   1039.49357
3           DIRIGIA  2048.947284

Распределение регулярных выражений

(?P<Name>   # first named capture group - "Name"
    .*?     # match anything (non-greedy)
)
(?P<Area>   # second named group - "Area"
    \d+     # match one or more digits,
    (?:     
       \.   # decimal
       \d+  # trailing digits
    )?      # the `?` indicates floating point is optional
)

PS, чтобы преобразовать столбец "Площадь" в числовое значение, используйте pd.to_numeric.

2 голосов
/ 19 июня 2019

чувствую, что ты можешь просто сделать str.rsplit

df.Col1.str.rsplit(' ',1,expand=True).apply(lambda x : x.str.strip(),1)
Out[314]: 
                  0            1
0  APPLEGATE WINERY   455.292049
1        AMAND FARM   849.827192
2      COBB FARM ST   1039.49357
3           DIRIGIA  2048.947284
1 голос
/ 19 июня 2019

Вы можете использовать rsplit. Это разделит строку, начинающуюся справа.

pd.DataFrame(df.Col1.str.rsplit(' ',1).tolist(), columns = ['Name','Area'])

Result:
    Name                Area
0   APPLEGATE WINERY    455.292049
1   AMAND FARM          849.827192
2   COBB FARM ST       1039.49357
3   DIRIGIA            2048.947284
0 голосов
/ 19 июня 2019

Попробуйте это регулярное выражение:

df.Col1.str.extract('(.*\S)\s+([\d\.]+)')

Выход:

                  0            1
0  APPLEGATE WINERY   455.292049
1        AMAND FARM   849.827192
2      COBB FARM ST   1039.49357
3           DIRIGIA  2048.947284
...