使用df.at[]结合字典替换DataFrame列值出现AttributeError如何解决?
解决方案
报错原因
AttributeError: 'numpy.int8' object has no attribute 'replace'报错的核心原因是:df.at[i, 'state']取到的是单个numpy数值类型对象,replace是pandas的Series/DataFrame专属方法,单个数值不支持该调用。
此外你的代码还有两处语法错误需要先修正:
- 第二个if判断中
j['country]缺少闭合单引号,应为j['country'] - 加拿大映射字典中
1: 'Edmonton缺少闭合单引号,应为1: 'Edmonton'
方案1:修正原循环写法
如果要保留你原来的循环逻辑,直接用字典取值即可,不需要调用replace方法:
us_state = {1: 'Alabama', 2: 'Alaska', 3: 'Illinois', 4: 'Ohio'} can_state = {1: 'Edmonton', 2: 'Sasketchwan', 3: 'Manitoba'} def convert_state(df): for i, j in df.iterrows(): if j['country'] == 'United States': # 直接用字典取值,get方法兼容不存在的键 df.at[i, 'state_edit'] = us_state.get(j['state'], '未知') if j['country'] == 'Canada': df.at[i, 'state_edit'] = can_state.get(j['state'], '未知') return df
方案2:高效向量化实现(推荐)
iterrows循环在数据量较大时执行效率极低,推荐用pandas原生的map+布尔索引实现,性能提升非常明显:
us_state = {1: 'Alabama', 2: 'Alaska', 3: 'Illinois', 4: 'Ohio'} can_state = {1: 'Edmonton', 2: 'Sasketchwan', 3: 'Manitoba'} def convert_state(df): df['state_edit'] = None # 处理美国行映射 us_mask = df['country'] == 'United States' df.loc[us_mask, 'state_edit'] = df.loc[us_mask, 'state'].map(us_state) # 处理加拿大行映射 can_mask = df['country'] == 'Canada' df.loc[can_mask, 'state_edit'] = df.loc[can_mask, 'state'].map(can_state) return df
如果后续需要新增更多国家的映射规则,可以把映射关系整合为嵌套字典,用apply简化代码:
state_maps = { 'United States': {1: 'Alabama', 2: 'Alaska', 3: 'Illinois', 4: 'Ohio'}, 'Canada': {1: 'Edmonton', 2: 'Sasketchwan', 3: 'Manitoba'} } def convert_state(df): df['state_edit'] = df.apply(lambda x: state_maps[x['country']].get(x['state'], '未知'), axis=1) return df
测试效果
使用你提供的测试数据运行:
import pandas as pd data = {'country':['United States', 'United States', 'Canada', 'United States'], 'state':[4, 2, 2, 1]} df = pd.DataFrame(data) df = convert_state(df) print(df)
输出结果:
country state state_edit 0 United States 4 Ohio 1 United States 2 Alaska 2 Canada 2 Sasketchwan 3 United States 1 Alabama
内容的提问来源于stack exchange,提问作者GK89
相关产品推荐
相关产品推荐

