Java Spark — разница в двух значениях столбцов в dataset / dataframe

#java #apache-spark

#java #apache-spark

Вопрос:

У меня есть приведенный ниже spark dataset / dataframe. Я должен создать новый столбец diff_col, найдя разницу между абсолютными значениями col_2 и col_3

 col_1 col_2 col_3
A     5      3
B     null  -2
C     2     null
D     null  null
E     3      1
F     4     -2
  

Ожидаемый результат:

 col_1 col_2 col_3 diff_col
A     5      3     2
B     null  -2    -2
C     2     null   2
D     null  null   0
E     3      1     2
F     4     -2     2
  

Не уверен, как это сделать в java spark. В pyspark мы можем сделать это, заменив null на lit(0), а затем col(col_2) — col(col_3). Существует ли эквивалент java spark для этого?

Ответ №1:

Вы можете использовать coalese [1] и lit [2], поскольку у вас всего два столбца.

     private Column absoluteBetweenTwo(final Dataset<Row> ds) {
        final Column col_1 = functions.coalesce(ds.col("col_1"), functions.lit(0));
        final Column col_2 = functions.coalesce(ds.col("col_2"), functions.lit(0));
        return functions.abs(col_1.minus(col_2));
    }

  

И чем добавить его в качестве столбца

     ds.withColumn("col_3", this.absoluteBetweenTwo(ds));
  

Альтернативное решение — явно обернуть ваше Dataset значение в DataFrameNaFunctions [3] и использовать fill в противном случае неприемлемый Java API.

fill заменит все NULL на заданное значение для столбцов соответствующего типа.

     return new DataFrameNaFunctions(ds).fill(0L);
  

1: https://spark.apache.org/docs/latest/api/java/org/apache/spark/sql/functions.html#coalesce-org.apache.spark.sql.Column…-

2: https://spark.apache.org/docs/latest/api/java/org/apache/spark/sql/functions.html#lit-java.lang .Объект-

3: https://spark.apache.org/docs/latest/api/scala/org/apache/spark/sql/DataFrameNaFunctions.html

Ответ №2:

Вы можете попробовать использовать метод fill, который создает другой набор данных, заменяя все нулевые значения на 0 (или любые другие числовые значения) для указанных столбцов. Затем вы можете продолжить вычисление разницы.

Ответ №3:

Используйте abs nvl SQL-функции внутри expr функции.

 df
.withColumn(
    "diff_col",
    expr("(abs(nvl(col_2,0)) - abs(nvl(col_3,0)))")
)
.show(false)
  

Вывод

  ----- ----- ----- -------- 
|col_1|col_2|col_3|diff_col|
 ----- ----- ----- -------- 
|A    |5    |3    |2       |
|B    |null |-2   |-2      |
|C    |2    |null |2       |
|D    |null |null |0       |
|E    |3    |1    |2       |
|F    |4    |-2   |2       |
 ----- ----- ----- --------