如何用.loc将str.extract结果赋值给筛选后的数据帧新列?
解决Pandas中.loc正则提取赋值为空的问题
核心问题分析
你遇到的.loc赋值后结果为空,本质是正则提取的结果索引与筛选行的索引未对齐。直接对全量reg_no执行提取后赋值,会因索引不匹配导致筛选行无法正确接收结果。
正确实现步骤
以下是用.loc安全实现需求的完整代码,附带示例数据:
1. 准备示例数据
import pandas as pd data = { 'reg_type': ['5008', '1234', '5008', '5008', '9999'], 'reg_no': ['AB12345', 'XYZ789', 'CD6789', '100001', 'EF567'] } df = pd.DataFrame(data)
2. 定义筛选条件
先创建掩码(mask)定位reg_type为'5008'的行:
mask = df['reg_type'] == '5008'
3. 对筛选后的行执行正则提取
仅对符合条件的reg_no进行提取,得到与筛选行索引一致的临时结果:
# 正则提取,返回包含两列的DataFrame extracted = df.loc[mask, 'reg_no'].str.extract(r'([A-Za-z]+)?(.+$)')
4. 用.loc将结果赋值到新增列
通过.loc精准定位筛选行的目标列,完成赋值:
# 先初始化列(可选,避免列不存在的警告) df['code'] = None df['number'] = None # 赋值提取结果 df.loc[mask, 'code'] = extracted[0] df.loc[mask, 'number'] = extracted[1]
关键注意事项
- 必须先筛选再提取:如果直接对全量
df['reg_no']执行提取,得到的结果包含所有行的索引,赋值给筛选行时会因索引不匹配导致空值。 - 正则中的
([A-Za-z]+)?是可选匹配,当reg_no无字母前缀时,code列会返回NaN,可通过fillna('')转为空字符串:df['code'] = df['code'].fillna('') - 避免链式索引:比如
df[mask]['code'] = ...这种写法会触发"设置值于切片副本"警告,.loc是Pandas官方推荐的安全赋值方式。
最终结果示例
执行上述代码后,DataFrame会变成:
| reg_type | reg_no | code | number |
|---|---|---|---|
| 5008 | AB12345 | AB | 12345 |
| 1234 | XYZ789 | None | None |
| 5008 | CD6789 | CD | 6789 |
| 5008 | 100001 | 100001 | |
| 9999 | EF567 | None | None |
内容的提问来源于stack exchange,提问作者Alex Howard
相关产品推荐
相关产品推荐

