将单个 Pandas 数据帧列中的字符串与数字分开,并创建两个新列



我很震惊以前没有人在SO上问过这个问题......因为这似乎是一个很简单的问题。

我在熊猫数据帧中有一列,如下所示:

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 中使用正则表达式,但这似乎有点矫枉过正,因为 a( 它只是数据类型的分离,b( 字符串具有不同的长度,数字具有不同的位数。

所以一个结果将开始看起来像这样:

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

但是,有没有一个漂亮、干净的解决方案来解决这个问题,而无需经历使用 RegEx 的麻烦,而是将数字中的字符串分成两列?

使用单个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 .

感觉你可以做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

你可以使用 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

试试这个正则表达式:

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

最新更新