pandas函数内调用fillna()报Timestamp无对应属性错误
错误原因
- 方法调用对象错误:使用
apply(axis=1)逐行处理时,row['year_of_release']是单元格级别的单个标量值,不是Series或DataFrame结构,本身不存在fillna()方法。报错里提到的Timestamp就是这个单元格非空值的实际类型,只有整列/全表这类批量结构才支持fillna()操作。 - 逻辑冗余无效:函数里写的
for i in row[['name','year_of_release']]循环只会拿到两个字段的列名,完全没有遍历处理的作用;就算fillna()能正常执行,也没有接收填充后的返回值,逻辑不会生效。 - 类型残留问题:
year_of_release字段之前存储过时间戳类型,部分非空值还保留Timestamp格式,没有完成全量int类型转换。
正确实现方案
前置步骤:清除类型残留
先把字段里残留的Timestamp值统一转为整数年份,设置为支持空值的Int64类型,避免类型不匹配问题:
import pandas as pd # 统一转换字段类型为可空整数年份 gaming['year_of_release'] = pd.to_datetime(gaming['year_of_release']).dt.year.astype('Int64')
注意:pandas的
Int64是支持空值存储的整数类型,和原生int64不同,填充空值后不会把整列转为浮点类型,符合按int类型处理的要求。
方案1:全量缺失值直接填充(性能最优)
不需要写自定义函数+apply循环,直接调用Series级别的fillna()即可完成全列缺失值替换,结果保持int类型:
# 把所有缺失的年份替换为你需要的默认int值,示例用0占位,可自行修改 gaming['year_of_release'] = gaming['year_of_release'].fillna(0)
方案2:指定条目单独填充
如果需要给特定游戏(比如LEGO Harry Potter: Years 5-7)的缺失年份单独赋值,其他行保留原值或走默认填充,直接用布尔索引做条件赋值即可,性能远高于apply循环:
# 定位目标行:游戏名匹配且年份为空 target_row_mask = (gaming['name'] == "LEGO Harry Potter: Years 5-7") & (gaming['year_of_release'].isna()) # 给目标行的缺失年份赋值2012 gaming.loc[target_row_mask, 'year_of_release'] = 2012 # 剩余其他行的缺失值如果需要统一填充,再执行全列fillna即可 # gaming['year_of_release'] = gaming['year_of_release'].fillna(默认填充int值)
参考:apply写法修正(不推荐,性能较差)
如果一定要用apply逐行处理的逻辑,需要判断单个值是否为空后直接返回对应结果,不能在标量值上调用fillna():
def fill_year(row): # 匹配目标游戏且年份为空时返回2012 if row['name'] == "LEGO Harry Potter: Years 5-7" and pd.isna(row['year_of_release']): return 2012 # 非空值、其他行直接返回原值,可自行扩展其他缺失值的填充规则 return row['year_of_release'] gaming['year_of_release'] = gaming.apply(fill_year, axis=1).astype('Int64')
内容的提问来源于stack exchange,提问作者Maor Ohayon
相关产品推荐
相关产品推荐

