【问题标题】:Upacking a list to select multiple columns from a spark data frame解包列表以从 spark 数据框中选择多个列
【发布时间】:2016-04-28 14:02:15
【问题描述】:

我有一个 spark 数据框 df。有没有办法使用这些列的列表子选择几列?

scala> df.columns
res0: Array[String] = Array("a", "b", "c", "d")

我知道我可以做类似df.select("b", "c") 的事情。但是假设我有一个包含几个列名val cols = List("b", "c") 的列表,有没有办法将它传递给 df.select? df.select(cols) 引发错误。类似于df.select(*cols) 在 python 中的东西

【问题讨论】:

    标签: apache-spark apache-spark-sql spark-dataframe


    【解决方案1】:

    使用df.select(cols.head, cols.tail: _*)

    让我知道它是否有效:)

    Explanation from @Ben:

    关键是select的方法签名:

    select(col: String, cols: String*)
    

    cols:String* 条目采用可变数量的参数。 :_* 解包参数,以便可以通过此参数处理它们。与使用*args 在python 中解包非常相似。有关其他示例,请参阅 herehere

    【讨论】:

    • 谢谢!像魅力一样工作。能多解释一下语法吗? col.tail: _ * 具体是做什么的?
    • 我想我现在明白了。关键是selectselect(col: String, cols: String*)的方法签名。 cols:String* 条目采用可变数量的参数。 :_* 解包参数,以便可以通过此参数处理它们。非常类似于在 python 中使用*args 解包。有关其他示例,请参阅 herehere
    • 酷!你说得对:)对不起,我刚刚收到了两个通知,所以无法早点回复。 :)
    • 没问题。再次感谢!
    【解决方案2】:

    您可以像这样将 String 类型转换为 spark 列:

    import org.apache.spark.sql.functions._
    df.select(cols.map(col): _*)
    

    【讨论】:

      【解决方案3】:

      我刚刚学到的另一个选项。

      import org.apache.spark.sql.functions.col
      val columns = Seq[String]("col1", "col2", "col3")
      val colNames = columns.map(name => col(name))
      val df = df.select(colNames:_*)
      

      【讨论】:

        【解决方案4】:

        首先将 String Array 转换为如下 Spark 数据集列类型的 List

        String[] strColNameArray = new String[]{"a", "b", "c", "d"};
        
        List<Column> colNames = new ArrayList<>();
        
        for(String strColName : strColNameArray){
            colNames.add(new Column(strColName));
        }
        

        然后在 select 语句中使用 JavaConversions 函数转换列表,如下所示。您需要以下导入语句。

        import scala.collection.JavaConversions;
        
        Dataset<Row> selectedDF = df.select(JavaConversions.asScalaBuffer(colNames ));
        

        【讨论】:

          【解决方案5】:

          您可以将Column* 类型的参数传递给select

          val df = spark.read.json("example.json")
          val cols: List[String] = List("a", "b")
          //convert string to Column
          val col: List[Column] = cols.map(df(_))
          df.select(col:_*)
          

          【讨论】:

          • 短一点的版本怎么样:df.select(cols.map(df(_)): _*)
          【解决方案6】:

          你可以这样做

          String[] originCols = ds.columns();
          ds.selectExpr(originCols)
          

          spark selectExp 源代码

               /**
             * Selects a set of SQL expressions. This is a variant of `select` that accepts
             * SQL expressions.
             *
             * {{{
             *   // The following are equivalent:
             *   ds.selectExpr("colA", "colB as newName", "abs(colC)")
             *   ds.select(expr("colA"), expr("colB as newName"), expr("abs(colC)"))
             * }}}
             *
             * @group untypedrel
             * @since 2.0.0
             */
            @scala.annotation.varargs
            def selectExpr(exprs: String*): DataFrame = {
              select(exprs.map { expr =>
                Column(sparkSession.sessionState.sqlParser.parseExpression(expr))
              }: _*)
            }
          

          【讨论】:

            【解决方案7】:

            是的,你可以在scala中使用.select

            使用 .head.tail 选择 List()

            中提到的所有值

            例子

            val cols = List("b", "c")
            df.select(cols.head,cols.tail: _*)
            

            Explanation

            【讨论】:

            • 你能分享一下如何在java中做同样的事情(传递列名)同时做dataframeResult = inpDataframe.select("col1","col2",....)
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2020-07-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-08-08
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多