Different floating point precision from RDD and DataFrame

最后都变了- 提交于 2019-12-10 17:28:02

问题


I changed an RDD to DataFrame and compared the results with another DataFrame which I imported using read.csv but the floating point precision is not the same from the two approaches. I appreciate your help.

The data I am using is from here.

from pyspark.sql import Row
from pyspark.sql.types import *

RDD way

orders = sc.textFile("retail_db/orders")
order_items = sc.textFile('retail_db/order_items')
orders_comp = orders.filter(lambda line: ((line.split(',')[-1] == 'CLOSED') or  (line.split(',')[-1] == 'COMPLETE')))
orders_compMap = orders_comp.map(lambda line: (int(line.split(',')[0]), line.split(',')[1]))

order_itemsMap = order_items.map(lambda line: (int(line.split(',')[1]), 
                                           (int(line.split(',')[2]), float(line.split(',')[4])) ))

 joined = orders_compMap.join(order_itemsMap)
 joined2 = joined.map(lambda line: ((line[1][0], line[1][1][0]), line[1][1][1]))

joined3 = joined2.reduceByKey(lambda a, b : a +b).sortByKey()

df1 = joined3.map(lambda x:Row(date = x[0][0], product_id = x[0][1], total  = x[1])).toDF().select(['date','product_id', 'total'])

DataFrame

 schema = StructType([StructField('order_id', IntegerType(), True),
                StructField('date', StringType(), True),
                StructField('customer_id', StringType(), True),
                 StructField('status', StringType(), True)])


 orders2 = spark.read.csv("retail_db/orders",schema = schema)


 schema = StructType([StructField('item_id', IntegerType(), True),
                StructField('order_id', IntegerType(), True),
                StructField('product_id', IntegerType(), True),
                 StructField('quantity', StringType(), True),
                 StructField('sub_total', FloatType(), True),
                 StructField('product_price', FloatType(), True)])



orders_items2 = spark.read.csv("retail_db/order_items", schema = schema)

orders2.registerTempTable("orders2t")
orders_items2.registerTempTable("orders_items2t")

 df2 = spark.sql('select o.date, oi.product_id, sum(oi.sub_total)  \
      as total from  orders2t as o inner join orders_items2t as oi on 
      o.order_id = oi.order_id \
      where o.status in ("CLOSED", "COMPLETE") group by o.date, 
     oi.product_id order by  o.date, oi.product_id')

Are they the same?

df1.registerTempTable("df1t")
df2.registerTempTable("df2t")

 spark.sql("select d1.total - d2.total as difference from df1t as d1 inner 
 join df2t as d2 on d1.date = d2.date \
 and d1.product_id =d2.product_id ").show(truncate = False)


回答1:


Ignoring loss of precision in conversions there are not the same.

  • Python

    According to Python's Floating Point Arithmetic: Issues and Limitations standard implementations use 64 bit representation:

    Almost all machines today (November 2000) use IEEE-754 floating point arithmetic, and almost all platforms map Python floats to IEEE-754 “double precision”. 754 doubles contain 53 bits of precision,

  • Spark SQL

    In Spark SQL FloatType uses 32 bit representation:

    FloatType: Represents 4-byte single-precision floating point numbers.

Using DoubleType might be closer:

DoubleType: Represents 8-byte double-precision floating point numbers.

but if predictable behavior is important you should use DecimalTypes with well defined precision.



来源:https://stackoverflow.com/questions/48465055/different-floating-point-precision-from-rdd-and-dataframe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!