我很震惊,以前没有人在SO上问过这个问题,因为这看起来像是一个简单的问题。
我在pandas数据框中只有一列,如下所示:
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中使用Regular Expressions,但这似乎有点过头了,因为a)只是数据类型的分隔,b)字符串的长度不同,数字的位数也不同。
所以一个结果将开始看起来像这样:
df['Name'] = df.Col1.str.extract('([A-Z]\w{0,})', expand=True)
df['Area'] = df.Col1.str.extract('(\d)', expand=True)
但是,有没有一种不错的,干净的解决方案可以解决此问题,而又不必麻烦使用RegEx并将字符串与数字分成两列呢?
答案 0 :(得分:6)
使用一个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,要将“ Area”列转换为数字,请使用pd.to_numeric
。
答案 1 :(得分:2)
感觉就像可以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
答案 2 :(得分:1)
您可以使用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
答案 3 :(得分:0)
尝试此正则表达式:
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