Применение, когда условие, только когда столбец существует в фрейме данных

Aug 17 2020

Я использую spark-sql-2.4.1v с java8. У меня есть сценарий, в котором мне нужно выполнить определенную операцию, если столбцы представлены в заданном списке столбцов фрейма данных

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

val data = List(
  ("20", "score", "school", "2018-03-31", 14 , 12 , 20),
  ("21", "score", "school", "2018-03-31", 13 , 13 , 21),
  ("22", "rate", "school", "2018-03-31", 11 , 14, 22),
  ("21", "rate", "school", "2018-03-31", 13 , 12, 23)
 )

val df = data.toDF("id", "code", "entity", "date", "column1", "column2" ,"column3"..."columnN")

как показано выше, столбцы «данных» фрейма данных не являются фиксированными и будут различаться и будут иметь «столбец1», «столбец2», «столбец3» ... «столбецN» ...

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

Я пытаюсь двумя способами использовать "when-cluase"

Первый способ:

 Dataset<Row> resultDs =  df.withColumn("column1_avg", 
                     when( df.schema().fieldNames().contains(col("column1")) , avg(col("column1"))))
                     )
 

Второй способ:

  Dataset<Row> resultDs =  df.withColumn("column2_sum", 
                     when( df.columns().contains(col("column2")) , sum(col("column1"))))
                     )

Ошибка:

Невозможно вызвать contains (Column) для типа массива String []

так как справиться с этим сценарием с помощью кода java8?

Ответы

1 Som Aug 17 2020 at 19:26

Вы можете создать столбец, содержащий все имена столбцов. затем вы можете проверить, присутствует ли столбец или нет, и обработать, если он доступен -

 df.withColumn("columns_available", array(df.columns.map(lit): _*))
      .withColumn("column1_org",
      when( array_contains(col("columns_available"),"column1") , col("column1")))
      .withColumn("x",
        when( array_contains(col("columns_available"),"column4") , col("column1")))
      .withColumn("column2_new",
        when( array_contains(col("columns_available"),"column2") , sqrt("column2")))
      .show(false)