Сумма массива PySpark с использованием функции SQL AGGREGATE дает неверный результат при приведении в виде float

#apache-spark

Вопрос:

Следующий код выдает результаты, которые немного отличаются от правильного результата, и мне было интересно, может ли кто-нибудь помочь определить, почему.

 import pyspark.sql.functions as f import pyspark.sql.types as t import pandas as pd  v1 = [24005, 24806874, 114187] v2 = [24005, 24806872, 114189] df = pd.DataFrame({"index": range(2), "arr": [v1, v2]})  schema = t.StructType(  [t.StructField("index", t.IntegerType(), True),  t.StructField("arr", t.ArrayType(t.LongType(), True)),  ] )  df = spark.createDataFrame(df, schema=schema) df = df.withColumn(  "sum",  f.expr("aggregate(arr, cast(0 as float), (acc, x) -gt; acc   x)") ) df.show(truncate=False)  # Output # ----- ------------------------- -----------  #|index|arr |sum | # ----- ------------------------- -----------  #|0 |[24005, 24806874, 114187]|2.4945068E7| #|1 |[24005, 24806872, 114189]|2.4945064E7| # ----- ------------------------- -----------   

Однако обновление float до double дает правильный результат:

 # Output # ----- ------------------------- -----------  #|index|arr |sum | # ----- ------------------------- -----------  #|0 |[24005, 24806874, 114187]|2.4945066E7| #|1 |[24005, 24806872, 114189]|2.4945066E7| # ----- ------------------------- -----------   

Я бы с удовольствием послушал ваши мысли!

Ответ №1:

Эффективные цифры десятичной части 32-разрядной floats обычно составляют 6-7 цифр. Результат вашего расчета составляет 8 цифр, что выходит за пределы диапазона с плавающей запятой, поэтому его точность не может быть гарантирована.