Dataframe 仅当数据帧中存在列时应用when条件

Dataframe 仅当数据帧中存在列时应用when条件,dataframe,apache-spark,apache-spark-sql,spark-streaming,Dataframe,Apache Spark,Apache Spark Sql,Spark Streaming,我正在使用spark-sql-2.4.1v和java8。我有一个场景,如果列出现在给定的dataframe列列表中,我需要执行某些操作 我有如下示例数据框,数据框的列将根据在数据库表上执行的外部查询而有所不同 val data = List( ("20", "score", "school", "2018-03-31", 14 , 12 , 20), ("21", "score&

我正在使用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")
如上所示,数据框中的“数据”列不是固定的,会有所不同,并且会有“column1”、“column2”、“column3”…“columnN”

因此,根据列的可用性,我需要执行一些操作 同样,我尝试使用“when子句”,当一个列出现时,我必须对指定的列执行某些操作,否则继续下一个操作

我尝试以下两种方式使用“when cluase”

第一种方式:

Dataset resultDs=df.withColumn(“column1_avg”,
当(df.schema().fieldNames()包含(列(“column1”)、平均值(列(“column1”))
)
第二种方式:

Dataset resultDs=df.withColumn(“column2_sum”,
当(df.columns()包含(col(“column2”)、sum(col(“column1”))时
)
错误:

无法对数组类型字符串[]调用contains(列)


那么如何使用java8代码处理此场景呢?您可以创建一个包含所有列名的列。然后,您可以检查列是否存在,并处理它是否可用-

df.withColumn(“columns\u可用”,数组(df.columns.map(点亮):\u*)
.withColumn(“column1_org”,
当(数组_包含(列(“列_可用”)、“列1”)、列(“列1”))
.withColumn(“x”,
当(数组_包含(列(“列_可用”)、“列4”)、列(“列1”))
.withColumn(“column2_new”,
当(数组_包含(列(“列_可用”)、“列2”)、sqrt(“列2”))
.show(假)

请显示预期output@thebluephantom预期输出是动态的,具体取决于列。。。i、 e.如果“column1”存在,则我将对column1进行平均,如果column2存在,则我将对column2进行求和,等等。。。。这里比较棘手的部分是,如果列没有“column1”,则操作不应该失败,因此我需要检查该列是否存在。函数
sum
avg
是聚合函数。它们通常返回一行。因此,您必须编辑您的问题,并展示您期望的输出示例。您可以做两个示例—一个是column1存在时,另一个是column1不存在时。显示输入ds和输出ds。非常感谢。。。但是有一个小小的疑问,如果没有指定的列存在,比如df.withColumn(“columns\u available”、array(df.columns.map(lit):\u*)、withColumn(“column1\u org”),当(array\u包含(cols(“columns\u available”)、“columnN”)、column2)时。show(false),它不应该显示该列,即“column1\u org”如何实现它?这是使用
withColumn
无法实现的。如果列不可用,为什么要首先添加
with column
。你能详细说明这个非常奇怪的要求的动机吗?我有基于特定列的要求,我需要执行特定的操作,如果列不可用,则不执行的操作是特定于特定列的操作。对于某些列,如果存在无效数据,它也可能为null。。。但是,如果我在这里添加null,那么它可能会被视为无效数据,但在这里不是这样的……df.columns.map(lit)在这里做什么?*?当我在java数组(Arrays.asList(df.columns()).stream().map(s->new Column(s)).toArray(Column[]::new))中执行此操作时,它实际获取的是columns值而不是columnscan。您能告诉我访问此广播变量有什么问题吗?
 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"))))
                     )