首页 > 解决方案 > 在 Dataframe float32 列上使用 list(zip(...)) 时出现浮动问题

问题描述

在尝试从两个单独的列创建一个由纬度和经度坐标组成的元组列时,我偶然发现它是 、 列表推导zip等的一个非常快速的替代方案itertuples。它需要很快,因为我正在处理大约 4M 行而且我不想把时间浪费在属性创建上。

好消息是,通过查看此代码的输出,我的问题完美地问自己:发生了什么,如何防止这种情况发生?我绝对肯定的是,例如52.353500,它尽可能精确,并且 Dataframe 不仅仅是为了查看而将其截断——因为这已经等于(非常粗略的)10 厘米的位置精度。

print(df['lat'].head())
print(df['long'].head())
list(zip(df['lat'].head(), df['long'].head()))

输出:

14    52.353500
37    52.355511
42    52.354019
44    52.373829
83    52.354599
Name: lat, dtype: float32

14    5.00611
37    4.90732
42    4.92045
44    4.84816
83    4.89405
Name: long, dtype: float32

[(52.35350036621094, 5.006110191345215),
 (52.35551071166992, 4.907320022583008),
 (52.35401916503906, 4.920450210571289),
 (52.37382888793945, 4.8481597900390625),
 (52.35459899902344, 4.894050121307373)]

根据要求:Dataframe 是使用read_csvwith dtypefloat32为两列加载的。

解决方案:这是我不知道浮点数系列表示的局限性,float_precision在读取数据时不使用并float32float_precision. 孩子们,使用floatdtype 并让 Pandas 决定(使用float64)。

标签: pythonpandasnumpy

解决方案


这是完美定义的行为,pandas 会根据预设精度截断尾随数字:

import math  

math.pi  
# 3.141592653589793

pi 在这里有 15 位精度。然而,在一个系列中,它并没有这样显示:

pd.Series([math.pi])                                                                                                   

0    3.141593
dtype: float64

pd.Series([math.pi]) .tolist()                                                                                         
# [3.141592653589793]

这是因为,

pd.get_option('precision')                                                                                             
# 6

阅读有关选项和设置以及如何更改它们的更多信息。

如果您想实际将您的浮点数舍入到某个精度,请使用round

pd.Series([math.pi]).round(decimals=6).tolist()                                                                        
# [3.141593]

推荐阅读