DataFrame列与数组匹配失败及索引越界问题求助
问题根源:浮点数精度误差
你遇到的问题其实是浮点数的二进制存储精度问题导致的。比如np.arange(0.,1.,0.1)生成的数值并不是精确的十进制小数——举个例子,0.4在这个数组里实际存储的是0.4000000000000001,而np.arange(0.9,0.,-0.1)生成的0.4却是精确的0.4,直接用==比较时,这两个值会被判定为不相等,导致返回空Series;而第二次出现在in2里的0.4是np.arange(0.,0.9,0.1)生成的,和df1里的0.4000000000000001一致,所以能匹配成功。
解决方案
方案1:用近似匹配代替精确相等
使用numpy.isclose()函数来判断两个浮点数是否近似相等(默认允许的误差范围已经足够处理这类累加产生的精度问题):
修改循环内的匹配代码:
for i in range(len(in_func)): # 用isclose做近似匹配 a = df1.loc[np.isclose(df1['input'], in_func[i]), 'output'] # 加个判断避免空Series触发索引错误 if not a.empty: b[i] = a.iloc[0] else: # 处理匹配不到的情况,比如赋值NaN或者其他默认值 b[i] = np.nan
方案2:四舍五入到固定小数位
既然你的数值都是保留1位小数的,可以直接把所有值四舍五入到1位小数后再比较:
# 提前给df1的input列做四舍五入 df1['input'] = df1['input'].round(1) # in_func也做同样处理 in_func = np.round(in_func, 1) # 之后原来的循环代码就可以正常运行了 for i in range(len(in_func)): a = df1.loc[df1['input']==in_func[i], 'output'] b[i] = a.iloc[0]
方案3:用pandas合并代替循环(更高效)
如果数据量较大,循环会比较慢,推荐用merge方法直接关联两个数据集,同时处理精度问题:
# 把in_func转成DataFrame并处理精度 in_df = pd.DataFrame({'input': in_func}) in_df['input_rounded'] = in_df['input'].round(1) # 给原df1也加一个精度处理后的列 df1['input_rounded'] = df1['input'].round(1) # 合并两个DataFrame,按处理后的列关联 merged_df = in_df.merge(df1, on='input_rounded', how='left') # 直接提取output列作为结果数组 b = merged_df['output'].values
这个方法不仅避免了循环,还自动处理了所有匹配情况,不会出现索引越界的错误。
内容的提问来源于stack exchange,提问作者fouk
相关产品推荐
相关产品推荐

