Databricks中Pandas DataFrame浮点列保留两位小数失败求助
问题分析与解决建议
1. 明显错误点
你遇到的核心问题是浮点数的二进制存储精度缺陷,加上处理时没从数据类型层面彻底解决问题:
- 仅用
round()等方法做数值四舍五入,但仍保留float类型存储——这类二进制浮点数无法精确表示大部分十进制小数,写入SQL数据库后会因存储机制暴露精度偏差; - 写入SQL时未指定精确小数类型(比如依然用
FLOAT而非DECIMAL/NUMERIC),数据库按浮点型存储自然带误差。
2. 解决建议
方案一:Pandas中转换为Decimal类型再写入
先把浮点列转为精确的十进制类型,从根源避免二进制浮点误差:
import pandas as pd from decimal import Decimal, ROUND_HALF_UP # 对目标列做四舍五入并转为Decimal类型 df['target_col'] = df['target_col'].apply( lambda x: Decimal(str(x)).quantize(Decimal('0.00'), rounding=ROUND_HALF_UP) ) # 写入SQL时指定列类型为DECIMAL from sqlalchemy import types df.to_sql( name='your_table', con=your_db_connection, dtype={'target_col': types.Numeric(precision=10, scale=2)} )
方案二:用Databricks Spark DataFrame处理(适配环境)
既然在Databricks环境,直接用Spark处理更稳妥,Spark对Decimal类型的支持更完善:
# Pandas转Spark DataFrame spark_df = spark.createDataFrame(df) # 四舍五入后转为DecimalType from pyspark.sql.types import DecimalType from pyspark.sql.functions import round spark_df = spark_df.withColumn( 'target_col', round(spark_df['target_col'], 2).cast(DecimalType(10, 2)) ) # 写入SQL数据库(以JDBC为例) spark_df.write.jdbc( url='your_jdbc_url', table='your_table', mode='append', properties={'user': 'your_user', 'password': 'your_pwd'} )
方案三:写入时强制指定SQL列类型
如果坚持用Pandas写入,必须在to_sql里明确指定列的精确小数类型,让数据库按规则存储:
from sqlalchemy import types # 先做数值四舍五入 df['target_col'] = df['target_col'].round(2) # 写入时指定列类型为DECIMAL df.to_sql( name='your_table', con=your_db_connection, dtype={'target_col': types.Numeric(precision=10, scale=2)} )
内容的提问来源于stack exchange,提问作者Tanjil
相关产品推荐
相关产品推荐

