【问题标题】:Select Columns in Spark Dataframe based on Column name pattern根据列名模式选择 Spark Dataframe 中的列
【发布时间】:2020-03-22 17:03:27
【问题描述】:

我有一个具有以下列结构的 spark 数据框:

UT_LVL_17_CD,UT_LVL_20_CD, 2017 1Q,2017 2Q,2017 3Q,2017 4Q, 2017 FY,2018 1Q, 2018 2Q,2018 3Q,2018 4Q,2018 FY

在上面的列结构中,我会得到新的列以及后续季度,如2019 1Q , 2019 2Q

我想选择UT_LVL_17_CD,UT_LVL_20_CD 和具有year<space>quarter 模式的列,例如2017 1Q。 基本上我想避免选择像 2017 FY , 2018 FY 这样的列,这必须是动态的,因为我每年都会获得新的 FY 数据

我正在使用 spark 2.4.4

【问题讨论】:

  • 请正确更新问题格式
  • 您的帖子存在格式问题。很难理解……

标签: scala apache-spark apache-spark-sql


【解决方案1】:

正如我在评论中所说,这可以通过使用 Regex 的普通 scala 来完成,因为 DataFrame 可以将列名称作为 Seq[String] 返回:

scala> val columns = df.columns 
// columns: Seq[String] = List(UT_LVL_17_CD, UT_LVL_20_CD, 2017 1Q, 2017 2Q, 2017 3Q, 2017 4Q, 2017 FY, 2018 1Q, 2018 2Q, 2018 3Q, 2018 4Q, 2018 FY)

scala> val regex = """^((?!FY).)*$""".r
// regex: scala.util.matching.Regex = ^((?!FY).)*$

scala> val selection = columns.filter(s => regex.findFirstIn(s).isDefined)
// selection: Seq[String] = List(UT_LVL_17_CD, UT_LVL_20_CD, 2017 1Q, 2017 2Q, 2017 3Q, 2017 4Q, 2018 1Q, 2018 2Q, 2018 3Q, 2018 4Q)

您可以检查所选列是否不包含不需要的列:

scala> columns.diff(selection)
// res2: Seq[String] = List(2017 FY, 2018 FY)

现在您可以使用selection

scala> df.select(selection.head, selection.tail : _*)
// res3: org.apache.spark.sql.DataFrame = [UT_LVL_17_CD: int, UT_LVL_20_CD: int ... 8 more fields]

【讨论】:

    【解决方案2】:

    您可以使用 desc sql 命令获取列名列表

        val fyStringList=new util.ArrayList[String]()
        spark.sql("desc <table_name>").select("col_name").filter(str => str.getString(0).toLowerCase.contains("fy")).collect.foreach(str=>fyStringList.add(str.getString(0)))
        println(fyStringList)
    

    使用上面的 sn-p 获取包含“fy”的列名列表 您可以使用正则表达式更新过滤器逻辑,也可以更新 forEach 中的逻辑以存储字符串列

    【讨论】:

      【解决方案3】:

      你可以试试这个sn-p。假设 DF 是由所有这些列组成的数据框。

      var DF1 =  DF.select(DF.columns.filter(x => !x.contains("FY")).map(DF(_)) : _*)
      

      这将删除那些与 FY 相关的列。希望这对你有用。

      【讨论】:

      • 我正在使用你的答案,它工作正常。下面是我的 command.select(final_df.columns.filter(x => x.contains("split")).map(final_df()) : _*)在列名中包含拆分。如果我想在输出中包含更多列,请告诉我如何实现这一点。
      猜你喜欢
      • 2022-10-16
      • 1970-01-01
      • 2020-04-22
      • 1970-01-01
      • 2019-01-12
      • 2017-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多