在Polars中检测浮点型坐标数据精度的简洁实现方案
在Polars中检测浮点型坐标数据精度的简洁实现方案
嘿,我完全懂你的感受——原来的代码确实有点重复啰嗦,就像你说的“按行付费”写出来的😅。咱们来把这个逻辑简化一下,既保留功能,又让代码更清爽!
核心痛点:重复的列处理逻辑
原来的代码对lat和lng做了几乎一模一样的操作:转字符串、分割、拆结构体、计算长度,重复代码太多。咱们的优化方向就是复用逻辑、批量处理,避免重复造轮子。
简洁实现方案
直接用Polars的批量列处理能力,一次搞定两列的精度计算,再求和得到总精度:
import polars as pl df = pl.DataFrame( { "lat": [ 43.6425047, 43.6, 40.688966, 40.6], "lng": [-79.3861057, -79.3, -74.044438, -74.0], } ) # 简洁版:批量处理+复用逻辑 df = df.with_columns( # 同时处理lat和lng,计算小数部分的长度 pl.col(["lat", "lng"]) .cast(pl.String) .str.split_exact(".", 1) # 按小数点分割成两部分(整数+小数) .struct.field(1) # 直接取出小数部分 .str.len_chars() # 计算小数部分的字符数(即精度位数) .name.suffix("_p") # 给结果列加后缀,比如lat→lat_p ).with_columns( # 求和得到总精度 (pl.col("lat_p") + pl.col("lng_p")).alias("precision") ).drop("lat_p", "lng_p") # 移除中间临时列 print(df.head())
运行结果和原代码完全一致
shape: (4, 3) ┌───────────┬────────────┬───────────┐ │ lat ┆ lng ┆ precision │ │ --- ┆ --- ┆ --- │ │ f64 ┆ f64 ┆ u32 │ ╞═══════════╪════════════╪═══════════╡ │ 43.642505 ┆ -79.386106 ┆ 14 │ │ 43.6 ┆ -79.3 ┆ 2 │ │ 40.688966 ┆ -74.044438 ┆ 12 │ │ 40.6 ┆ -74.0 ┆ 2 │ └───────────┴────────────┴───────────┘
优化点说明
- 批量处理列:用
pl.col(["lat", "lng"])一次性选中两列,避免重复写两次处理逻辑 - 简化结构体操作:直接用
.struct.field(1)取出小数部分,省去了重命名字段、拆结构体的步骤 - 自动命名结果列:用
.name.suffix("_p")统一给精度列加后缀,不用手动写别名 - 链式调用更紧凑:把中间步骤合并,减少不必要的
with_columns拆分
边界情况兼容
如果遇到没有小数部分的整数(比如lat=43),str.split_exact会返回("43", ""),此时str.len_chars()会得到0,完全符合“无小数精度”的预期。
为什么不用数学方法?
虽然可以用“乘以10直到整数”的数学思路计算小数位数,但浮点数的存储特性可能导致误差(比如0.1在二进制浮点数中是无限循环的),而转字符串的方法更直接可靠,和你原始数据的显示精度完全一致。
备注:内容来源于stack exchange,提问作者Kyle
相关产品推荐
相关产品推荐

