scala withcolumn仅当两列都存在时

vbopmzt1  于 2021-07-09  发布在  Spark
关注(0)|答案(1)|浏览(362)

我看到了这个问题的一些变化,但没有找到确切的我要找的。问题是:
我有一些报告的名称,我已经收集在一个Dataframe和数据透视。我遇到的问题是关于报告名称的弹性。我不能保证每90天就有一次数据,而且rpt1、rpt2和rpt3都会在那里。因此,如何仅在列存在时创建计算。我已经概述了我的代码现在的样子。如果所有列都在那里,它就可以工作,但是我想对它进行进一步的验证,以确保如果报告不在90天窗口中,管道线不会出错,而是跳过.withcolumn添加

  1. df1=(reports.alias("r")
  2. .groupBy(uniqueid)
  3. .filter("current_date<=90")
  4. .pivot(report_name)
  5. **
  6. Result would be the following columns uniqueid Rpt1, Rpt2, Rpt3
  7. * +---+-----+------+----------+
  8. * |id |Rpt1 |Rpt2 |Rpt3 |
  9. * +---+-----+------+----------+
  10. * |205|72 |36 | 12 |
  11. **
  12. df2=(df1.alias("d1")
  13. .withColumn("new_calc",expr("Rpt2/Rpt3"))
6mzjoqzu

6mzjoqzu1#

你可以用一个 Try monad并返回原始Dataframe,如果 withColumn 失败。

  1. import scala.util.Try
  2. val df2 = Try(df1.withColumn("new_calc", expr("Rpt2/Rpt3")))
  3. .getOrElse(df1)
  4. .alias("d1")

如果要重用,也可以将其定义为方法:

  1. import org.apache.spark.sql.Column
  2. def withColumnIfExist(df: DataFrame, colName: String, col: Column) =
  3. Try(df.withColumn("new_calc",expr("Rpt2/Rpt3"))).getOrElse(df)
  4. val df3 = withColumnIfExist(df1, "new_calc", expr("Rpt2/Rpt3"))
  5. .alias("d1")

如果需要链接多个转换,可以将其与 transform :

  1. val df4 = df1.alias("d1")
  2. .transform(withColumnIfExist(_, "new_calc", expr("Rpt2/Rpt3")))
  3. .transform(withColumnIfExist(_, "new_calc_2", expr("Rpt1/Rpt2")))

或者可以将其实现为 implicit class :

  1. implicit class RichDataFrame(df: DataFrame) {
  2. def withColumnIfExist(colName: String, col: Column): DataFrame =
  3. Try(df.withColumn("new_calc", expr("Rpt2/Rpt3"))).getOrElse(df)
  4. }
  5. val df5 = df1.alias("d1")
  6. .withColumnIfExist("new_calc", expr("Rpt2/Rpt3"))
  7. .withColumnIfExist("new_calc_2", expr("Rpt1/Rpt2"))

withColumn 适用于所有数据集,如果需要 withColumnIfExist 要对所有数据集(包括dataframe)进行常规操作,请执行以下操作:

  1. implicit class RichDataset[A](ds: Dataset[A]) {
  2. def withColumnIfExist(colName: String, col: Column): DataFrame =
  3. Try(ds.withColumn("new_calc", expr("Rpt2/Rpt3"))).getOrElse(ds.toDF)
  4. }
展开查看全部

相关问题