0


『Python - Azure Databricks』pyspark 数值精度,Decimal转Float

在对数据精度要求较高的任务中,将数据从数据源加载到数据库时不能损失精度,这时通常会使用到

      D 
     
    
      e 
     
    
      c 
     
    
      i 
     
    
      m 
     
    
      a 
     
    
      l 
     
    
   
     Decimal 
    
   
 Decimal 函数,有时候这些数据会导致异常,因为  
  
   
    
    
      p 
     
    
      a 
     
    
      n 
     
    
      d 
     
    
      a 
     
    
      s 
     
    
   
     pandas 
    
   
 pandas 不支持涉及  
  
   
    
    
      D 
     
    
      e 
     
    
      c 
     
    
      i 
     
    
      m 
     
    
      a 
     
    
      l 
     
    
   
     Decimal 
    
   
 Decimal 和  
  
   
    
    
      f 
     
    
      l 
     
    
      o 
     
    
      a 
     
    
      t 
     
    
   
     float 
    
   
 float 的混合运算,所以必须先统一数据类型

在这里插入图片描述

最简单粗暴的应对方法当然是直接对涉及运算的数值列进行

astype("float64")

操作了,不过缺点就是在代码量很大的情况下,这么做需要在多处修改,不仅麻烦还容易漏

所以我决定从源头解决问题 -> 把数据从Database捞过来后马上转型,这样就不用修改后续需要执行的代码了

捞数

from pyspark.sql import SparkSession
session = SparkSession.builder.getOrCreate()
spark_df = session.sql('select * from testing_table')# 展示列及其数据类型,返回的是元组列表
spark_df.dtypes
# [('name', 'string'),# ('price', 'decimal(16,8)'),# ('rate', 'decimal(16,8)')]

判断、转型

由于16位有效数字已经满足我任务的精度要求,所以下面的代码直接将

      D 
     
    
      e 
     
    
      c 
     
    
      i 
     
    
      m 
     
    
      a 
     
    
      l 
     
    
      ( 
     
    
      16 
     
    
      , 
     
    
      8 
     
    
      ) 
     
    
   
     Decimal(16,8) 
    
   
 Decimal(16,8) 转为双精度  
  
   
    
    
      D 
     
    
      o 
     
    
      u 
     
    
      b 
     
    
      l 
     
    
      e 
     
    
      T 
     
    
      y 
     
    
      p 
     
    
      e 
     
    
   
     DoubleType 
    
   
 DoubleType ,因为它们的有效数字都是16位,但在更高精度的场景下则不能这么转,如  
  
   
    
    
      D 
     
    
      e 
     
    
      c 
     
    
      i 
     
    
      m 
     
    
      a 
     
    
      l 
     
    
      ( 
     
    
      32 
     
    
      , 
     
    
      16 
     
    
      ) 
     
    
   
     Decimal(32,16) 
    
   
 Decimal(32,16) 转为  
  
   
    
    
      D 
     
    
      o 
     
    
      u 
     
    
      b 
     
    
      l 
     
    
      e 
     
    
      T 
     
    
      y 
     
    
      p 
     
    
      e 
     
    
   
     DoubleType 
    
   
 DoubleType 会损失精度

pyspark -

cast
from pyspark.sql.types import DoubleType
from pyspark.sql.functions import col
for c in spark_df.columns:if'decimal'indict(spark_df.dtypes)[c]:
        spark_df = spark_df.withColumn(c, col(c).cast(DoubleType()))

pandas -

astype

|

float

      p 
     
    
      a 
     
    
      n 
     
    
      d 
     
    
      a 
     
    
      s 
     
    
   
     pandas 
    
   
 pandas 这边转也行,但它  
  
   
    
    
      d 
     
    
      t 
     
    
      y 
     
    
      p 
     
    
      e 
     
    
      s 
     
    
   
     dtypes 
    
   
 dtypes 接口的算法比较迷,经常会把数值列的类型判断为  
  
   
    
    
      o 
     
    
      b 
     
    
      j 
     
    
      e 
     
    
      c 
     
    
      t 
     
    
   
     object 
    
   
 object 而不是  
  
   
    
    
      f 
     
    
      l 
     
    
      o 
     
    
      a 
     
    
      t 
     
    
      64 
     
    
   
     float64 
    
   
 float64,因此列类型的判断还是得在转  
  
   
    
    
      p 
     
    
      a 
     
    
      n 
     
    
      d 
     
    
      a 
     
    
      s 
     
    
   
     pandas 
    
   
 pandas前做
decimal_cols =[k for k, v in spark_df.dtypes if'decimal'in v]
pandas_df = spark_df.toPandas()for col in decimal_cols:
    pandas_df[col]= pandas_df[col].astype('float64')# 在有脏数据的情况下,只能一个一个地判断了# 备用方案from decimal import Decimal
    pandas_df[col]= pandas_df[col].apply(lambda x:float(x)ifisinstance(x, Decimal)else x)

参考:
PySpark basics


本文转载自: https://blog.csdn.net/m0_47149835/article/details/143208340
版权归原作者 Python捞数人 所有, 如有侵权,请联系我们删除。

“『Python - Azure Databricks』pyspark 数值精度,Decimal转Float”的评论:

还没有评论