2017-02-10 2 views
0

у меня есть Dataframe с такого рода данных:О потере точности при расчете совокупной суммы с кадрами данных

unit,sensitivity currency,trading desk ,portfolio  ,issuer  ,bucket ,underlying ,delta  ,converted sensitivity 
ES ,USD     ,EQ DERIVATIVES,ESEQRED_LH_MIDX ,5GOY   ,5  ,repo  ,0.00002  ,0.00002 
ES ,USD     ,EQ DERIVATIVES,IND_GLOBAL1  ,no_localizado ,8  ,repo  ,-0.16962  ,-0.15198 
ES ,EUR     ,EQ DERIVATIVES,ESEQ_UKFLOWN ,IGN2   ,8  ,repo  ,-0.00253  ,-0.00253 
ES ,USD     ,EQ DERIVATIVES,BASKETS1  ,9YFV   ,5  ,spot  ,-1003.64501 ,-899.24586 

, и я должен сделать операцию агрегации над этими данными, делать что-то вроде этого:

val filteredDF = myDF.filter("unit = 'ES' AND `trading desk` = 'EQ DERIVATIVES' AND issuer = '5GOY' AND bucket = 5 AND underlying = 'repo' AND portfolio ='ESEQRED_LH_MIDX'") 
        .groupBy("unit","trading desk","portfolio","issuer","bucket","underlying") 
        .agg(sum("converted_sensitivity")) 

Но я вижу, что я теряю точность на агрегированной суммы, так как я могу быть уверен, что каждому значению «converted_sensitivity» преобразуется в BigDecimal (25,5) перед выполнением операции суммы над новым агрегированным столбцом?

спасибо.

+0

Вы можете выполнить операцию карты, чтобы сначала вычислить версию столбца BigDecimal, а затем добавить их в следующую операцию. Я думаю, что это было бы между .groupBy и .agg – Paul

ответ

1

Чтобы убедиться в конверсии, вы можете использовать DecimalType в вашем DataFrame.

В соответствии с искровой документацией DecimalType является:

Типа данных, представляющим значение java.math.BigDecimal. Десятичное число, которое должно иметь фиксированную точность (максимальное количество цифр) и масштаб (количество цифр на правой стороне точки). Точность может быть до 38, масштаб также может быть до 38 (меньше или равно точности). Точность и масштаб по умолчанию (10, 0).

Вы можете увидеть это here.

Для преобразования данных вы можете использовать функцию cast объекта Column. Вот так:

import org.apache.spark.sql.types.DecimalType 

val filteredDF = myDF.filter("unit = 'ES' AND `trading desk` = 'EQ DERIVATIVES' AND issuer = '5GOY' AND bucket = 5 AND underlying = 'repo' AND portfolio ='ESEQRED_LH_MIDX'") 
       .withColumn("new_column_big_decimal", col("converted_sensitivity").cast(DecimalType(25,5)) 
       .groupBy("unit","trading desk","portfolio","issuer","bucket","underlying") 
       .agg(sum("new_column_big_decimal")) 
+1

perfect @Thiago, только то, что мне нужно было знать, спасибо вам большое! – aironman