如何用Pandas数组采样替换DataFrame中X值?为何结果被舍入?
问题描述
现有Pandas DataFrame:
import pandas as pd df = pd.DataFrame({'A': [0.1, 0.1, 0.1, 0.1, 'X'], 'B': [0.1, 0.1, 'X', 0.1, 0.1], 'C': [0.1, 'X', 'X', 'X', 'X']})
对应数据:
A B C 0 0.1 0.1 0.1 1 0.1 0.1 X 2 0.1 X X 3 0.1 0.1 X 4 X 0.1 X
另有Pandas数组:
arr = pd.array([0.9999999999999304, 0.9999973764241584, 0.9999997377248664, 0.9615117313882438, 0.871479832883895, 0.9999999999998652, 0.9999999999999994, 0.9999029359407972, 0.999999984174712, 0.9944689702907784], dtype='float64')
需求:从该数组中随机采样,替换DataFrame里所有的X值,同时保留数组的分布特征。
尝试代码:
import numpy as np df[df == 'X'] = np.random.choice(arr, replace=True)
疑问:
- 这段代码是否实现了随机采样?
- 为什么替换后的值都显示为1.0而非数组的精确值?
- 如何实现精确替换?
问题解答
1. 是否实现了随机采样?
是的,这段代码已经在执行随机采样。np.random.choice(arr, replace=True)会从输入数组arr中有放回地随机选取元素,选取的数量等于DataFrame中X的总个数(此处为7个)。只是后续的显示问题让你误以为采样未生效。
2. 为何值被舍入为1.0?
核心原因是DataFrame的列类型为object:原数据混合了浮点数(0.1)和字符串('X'),Pandas会自动将列的 dtype 设为object。当你把浮点型采样值赋值给object类型列时,Pandas默认的显示设置会对接近1.0的浮点数做截断格式化,看起来像是变成了1.0,但实际存储的仍是精确值(可通过df.loc[1, 'C']查看单个元素的真实值验证)。
3. 如何实现精确替换并正确显示?
解决思路是统一列的数值类型,或调整显示设置,具体方法如下:
方法一:转换列类型后替换(推荐)
先将X替换为缺失值,把列转为浮点型,再用采样值填充缺失值:
# 替换X为缺失值,转float64类型 df = df.replace('X', pd.NA).astype('float64') # 统计缺失值总数 nan_count = df.isna().sum().sum() # 采样并填充缺失值 df = df.fillna(pd.Series(np.random.choice(arr, nan_count), index=df.isna().stack()[lambda x: x].index))
方法二:调整Pandas显示设置
如果不想修改列类型,可强制让Pandas显示完整小数位数:
import pandas as pd # 设置显示所有小数位数 pd.set_option('display.float_format', lambda x: '%.15f' % x) # 执行替换 df[df == 'X'] = np.random.choice(arr, replace=True)
此方法能看到精确采样值,但列类型仍为object,后续数值运算可能有额外开销。
更简洁的写法
df = df.replace('X', pd.NA).astype('float64').apply(lambda col: col.fillna(np.random.choice(arr, col.isna().sum())))
内容的提问来源于stack exchange,提问作者peter_parker
相关产品推荐
相关产品推荐

