Spark scala несоответствие уровня столбца для двух информационных фреймов - PullRequest
0 голосов
/ 12 апреля 2020

У меня есть 2 кадра данных


val df1 = Seq((1, "1","6"), (2, "10","8"), (3, "6","4")).toDF("id", "value1","value2")
val df2 = Seq((1, "1","6"), (2, "5","4"), (4, "3","1")).toDF("id", "value1","value2")

, и я хочу найти разницу выходных данных уровня столбца, которая должна выглядеть как

id,value1_df1,value1_df2,diff_value1,value2_df1,value_df2,diff_value2
1, 1        ,1           ,  0         , 6         ,6         ,0
2, 10       ,5           ,  5         , 8         ,4         ,4
3, 6        ,3           ,  1         , 4         ,1         ,3

, как у меня есть 100 столбцов и хочу вычислить разницу между одним и тем же столбцом в двух столбцах данных: Dynami c

1 Ответ

1 голос
/ 12 апреля 2020

Может быть, это поможет:

  val spark = SparkSession.builder.appName("Test").master("local[*]").getOrCreate();

  import spark.implicits._

  var df1 = Seq((1, "1", "6"), (2, "10", "8"), (3, "6", "4")).toDF("id", "value1", "value2")
  var df2 = Seq((1, "1", "6"), (2, "5", "4"), (3, "3", "1")).toDF("id", "value1", "value2")

  df1.columns.foreach(column => {
    df1 = df1.withColumn(column, df1.col(column).cast(IntegerType))
  })
  df2.columns.foreach(column => {
    df2 = df2.withColumn(column, df2.col(column).cast(IntegerType))
  })

  df1 = df1.withColumnRenamed("id", "df1_id")
  df2 = df2.withColumnRenamed("id", "df2_id")

  df1.show()
  df2.show()

, поэтому до сих пор у вас есть два кадра данных со значениями_x, value_y, value_z и продолжением ...

df1:

+------+------+------+
|df1_id|value1|value2|
+------+------+------+
|     1|     1|     6|
|     2|    10|     8|
|     3|     6|     4|
+------+------+------+

df2:

+------+------+------+
|df2_id|value1|value2|
+------+------+------+
|     1|     1|     6|
|     2|     5|     4|
|     3|     3|     1|
+------+------+------+

Теперь мы собираемся присоединиться к ним на основе идентификатора:

  var df3 = df1.alias("df1").join(df2.alias("df2"), $"df1.df1_id" === $"df2.df2_id")

и, наконец, мы возьмем все столбцы в df1 / df2 (* Важно, чтобы они будут иметь одинаковые столбцы) - без идентификатора, и создайте новый столбец различий:

  df1.columns.tail.foreach(col => {
    val new_col_name = s"${col}-diff"
    val df_a_col = s"df1.${col}"
    val df_b_col = s"df2.${col}"
    df3 = df3.withColumn(new_col_name, df3.col(df_a_col) - df3.col(df_b_col))
  })

  df3.show()

Результат:

+------+------+------+------+------+------+-----------+-----------+
|df1_id|value1|value2|df2_id|value1|value2|value1-diff|value2-diff|
+------+------+------+------+------+------+-----------+-----------+
|     1|     1|     6|     1|     1|     6|          0|          0|
|     2|    10|     8|     2|     5|     4|          5|          4|
|     3|     6|     4|     3|     3|     1|          3|          3|
+------+------+------+------+------+------+-----------+-----------+

Это результат, и это Dynami c, так что вы можете добавить значение X вы хотите.

...