Python DataFrame用ffill(axis=1)填充后数据类型变为object的问题
问题原因与解决方法
原因分析
你遇到的类型变更问题,核心是行方向填充(axis=1)时跨数据类型列填充,导致列内出现混合类型:
- pandas的
ffill(axis=1)按行从前到后填充,若某一行的数值型列(int64/float64)存在NaN,且前面的列是非数值类型(比如字符串),填充后该数值列会混入非数值数据,pandas只能将列类型转为object来兼容混合类型。 - 若所有列都是数值型,int64列的NaN被float64值填充只会转为float64,不会变成object;只有混合了非数值类型才会触发object类型转换。
解决方法
方法一:仅对数值型列执行行填充
先筛选出所有数值型列,单独对这些列做行方向填充,避免非数值列的值污染数值列:
# 筛选出int64和float64类型的列 numeric_cols = t.select_dtypes(include=['int64', 'float64']).columns # 仅对数值型列执行行向前填充 t[numeric_cols] = t[numeric_cols].ffill(axis=1)
方法二:填充后强制转换列类型
如果确认填充后的数值列应该保持原类型(比如day_lag填充后都是整数),可以手动强制转换:
# 转换int类型列 t['day_lag'] = t['day_lag'].astype('int64') t['clean_amt'] = t['clean_amt'].astype('int64') # 转换所有d开头的float类型列 d_cols = [col for col in t.columns if col.startswith('d')] t[d_cols] = t[d_cols].astype('float64')
注意:转换int64时,如果列中存在非整数值会报错,需提前确认填充后的值都是整数。
方法三:排查并修正混合类型源头
可以先检查哪些数值列混入了非数值数据,定位问题行:
# 检查day_lag列是否存在非数值元素 print(t[t['day_lag'].apply(lambda x: not isinstance(x, (int, float)))])
如果确实是前面的非数值列导致的,可调整填充范围,仅在数值列内部进行横向填充。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

