Python 在单个Dataframe列中将字符串与数值分开,并创建两个新列

Python 在单个Dataframe列中将字符串与数值分开,并创建两个新列,python,pandas,dataframe,extract,Python,Pandas,Dataframe,Extract,我很震惊,以前没有人问过这个问题。。因为这似乎是一个足够简单的问题 熊猫数据框中有一列,如下所示: 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.29

我很震惊,以前没有人问过这个问题。。因为这似乎是一个足够简单的问题

熊猫数据框中有一列,如下所示:

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)
但是,有没有一个好的、干净的解决方案来解决这个问题,而不必经历使用正则表达式的麻烦,而是将字符串从数字分隔成两列?

试试这个正则表达式:

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

使用单个
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
df2=(df['Col1'].str.extract(r'(?P.*)(?P\d+(?:\。\d+))
.applymap(str.strip))
df2
名称区
0阿普尔盖特酒庄455.292049
1阿曼农场849.827192
科布农场街2号1039.49357
3迪里吉亚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
)
(?P#第一个命名的捕获组-“名称”
*?#匹配任何内容(非贪婪)
)
(?P#第二个命名组-“区域”
\d+#匹配一个或多个数字,
(?:     
\.#十进制
\d+#尾随数字
)?#``表示浮点是可选的
)

PS,若要将“区域”列转换为数字,请使用
pd。若要将数字转换为
,,您感觉只需执行
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.strip().str.rsplit(…)!你能给我一个32街的名字吗?不,所有的名字都是以字母开头的,不是数字。我非常感谢你对正则表达式的解释!多谢。为了使这个解决方案起作用,我还必须将数据帧转换为字符串
。astype(str)
,因为我以前遇到错误
只能使用带有字符串值的.str访问器,它在pandas中使用np.object uudtype
,但现在它可以工作了。@JAG2024不客气。正则表达式背后的思想是找到看起来像浮点数的内容,并将其捕获为第二组“区域”,然后将其之前的所有内容捕获为“名称”。很高兴这有帮助。