为何pandas.Series.str.extract可打印结果却无法赋值给变量?
问题原因与解决方案
核心问题
你的代码里str.extract默认返回DataFrame(哪怕只有一个捕获组),而你要赋值的df.loc[m, 'Street']是Series类型,维度不匹配导致赋值失败出现NaN;where方法报错也是因为传入的替换值是DataFrame,和原Series维度不一致。
解决方法
有两种方式可以修正:
方法1:使用expand=False返回Series
修改str.extract调用时加上expand=False参数,让它直接返回Series,和目标列维度匹配:
import pandas as pd import numpy as np df = pd.DataFrame( [ ['1', np.nan, np.nan, '1 Banana St, 69126 Heidelberg'], ['2', "Doloros St", 67898, '2 Choco Rd, 69412 Eberbach']], columns=['id', "Street", 'Postcode', 'FullAddress'] ) m = df['Street'].isna() # 提取Street,返回Series df.loc[m, 'Street'] = df.loc[m, 'FullAddress'].str.extract(r'(.+?),', expand=False) # 提取Postcode,返回Series df.loc[m, 'Postcode'] = df.loc[m, 'FullAddress'].str.extract(r'\b(\d{5})\b', expand=False) # where方法也可以正常使用 df["Street"] = df["Street"].where(~m, df["FullAddress"].str.extract(r'(.+?),', expand=False))
方法2:从提取的DataFrame中取出对应列
如果不想改expand参数,可以通过.iloc[:,0]从返回的DataFrame中取出第一列的Series再赋值:
df.loc[m, 'Street'] = df.loc[m, 'FullAddress'].str.extract(r'(.+?),').iloc[:,0] df.loc[m, 'Postcode'] = df.loc[m, 'FullAddress'].str.extract(r'\b(\d{5})\b').iloc[:,0] # where方法同理 df["Street"] = df["Street"].where(~m, df["FullAddress"].str.extract(r'(.+?),').iloc[:,0])
为什么原来的代码会失败?
str.extract默认expand=True,返回DataFrame。当给Series类型的df.loc[m, 'Street']赋值时,pandas会尝试将DataFrame的列名和目标Series的索引对齐,因为列名不匹配,最终赋值结果为NaN。where方法要求替换值的维度必须和原Series一致,传入DataFrame时就会抛出NotImplementedError。
内容的提问来源于stack exchange,提问作者DrWhat
相关产品推荐
相关产品推荐

