นำไปใช้เมื่อเงื่อนไขก็ต่อเมื่อมีคอลัมน์อยู่ในดาต้าเฟรม

Aug 17 2020

ฉันใช้ spark-sql-2.4.1v กับ java8 ฉันมีสถานการณ์ที่ฉันต้องดำเนินการบางอย่างหากคอลัมน์แสดงในรายการคอลัมน์ดาต้าเฟรมที่กำหนด

ฉันมีกรอบข้อมูลตัวอย่างด้านล่างคอลัมน์ของ dataframe จะแตกต่างกันไปตามแบบสอบถามภายนอกที่ดำเนินการบนตารางฐานข้อมูล

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")

ตามที่แสดงด้านบนคอลัมน์ "data" ของ dataframe ไม่ได้รับการแก้ไขและจะแตกต่างกันไปและจะมี "column1", "column2", "column3" ... "columnN" ...

ดังนั้นขึ้นอยู่กับความพร้อมใช้งานของคอลัมน์ฉันต้องดำเนินการบางอย่างสำหรับสิ่งเดียวกันฉันพยายามใช้ "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"))))
                     )

ข้อผิดพลาด:

ไม่สามารถเรียกมี (คอลัมน์) ในประเภทอาร์เรย์ 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)