使用df.where替换np.nan为None时非替换列隐式类型转换原因
为什么使用
df.where替换np.nan为None时非替换列会发生类型转换? 问题复现
import numpy as np import pandas as pd df = pd.DataFrame([{'a': 1.0, 'b': 1.1, 'c': True, 'd': np.nan,}]) print(df) # a b c d # 0 1.0 1.1 True NaN df_new = df.where((pd.notnull(df)), None) print(df_new) # a b c d # 0 1 1.1 True None print(df.dtypes) # a float64 # b float64 # c bool # d float64 # dtype: object print(df_new.dtypes) # a int64 <- 列a的类型从float64转换为int64! # b object # c bool # d object # dtype: object
环境信息:
$ python -V Python 3.7.5 $ pip freeze | grep -e pandas -e numpy numpy==1.21.6 pandas==1.2.5
原因分析
在pandas 1.2.x及更早版本中,df.where方法在将np.nan替换为None时,会触发全局的类型推断调整:
None在pandas中属于object类型,当任意一列被转换为object类型后,pandas的类型推断逻辑会对其他列进行「自动优化」。- 列a的原始值是
1.0(float64类型),由于该列没有缺失值,pandas会将其转换为int64类型,认为这是更合适的存储类型。 - 列b的
1.1无法转换为整数类型,因此被转为object类型;列c的布尔值未受影响,保留原类型;列d因被替换为None,直接转为object类型。
版本修复说明
pandas 1.3.0及以上版本修复了这个问题,优化了where方法的类型处理逻辑,会尽可能保留原始列的数据类型,不会再出现这种不必要的隐式类型转换。
内容的提问来源于stack exchange,提问作者machi-da
相关产品推荐
相关产品推荐

