解包列表以从Spark Dataframe 中选择多个列

djp7away  于 2022-12-13  发布在  Apache
关注(0)|答案(8)|浏览(147)

我有一个spark Dataframe 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)抛出一个错误。

t9aqgxwy

t9aqgxwy1#

使用df.select(cols.head, cols.tail: _*)
让我知道它是否有效:)
@Ben的解释:
关键是select的方法签名:

select(col: String, cols: String*)

cols:String*条目接受可变数量的参数。:_*解包参数,以便可以通过此参数处理它们。非常类似于python中使用*args解包。其他示例请参见herehere

prdp8dxp

prdp8dxp2#

您可以将String类型转换为spark列,如下所示:

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

iyzzxitl3#

我刚学会的另一个选择。

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:_*)
pb3s4cty

pb3s4cty4#

首先将String Array转换为Spark数据集的List Column类型,如下所示

String[] strColNameArray = new String[]{"a", "b", "c", "d"};

List<Column> colNames = new ArrayList<>();

for(String strColName : strColNameArray){
    colNames.add(new Column(strColName));
}

然后在select语句中使用JavaConversions函数转换List,如下所示。

import scala.collection.JavaConversions;

Dataset<Row> selectedDF = df.select(JavaConversions.asScalaBuffer(colNames ));
jw5wzhpr

jw5wzhpr5#

您可以将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:_*)
wribegjk

wribegjk6#

你可以这样做

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))
    }: _*)
  }
jmo0nnb3

jmo0nnb37#

是的,你可以在scala中使用**.select**。
使用**.head.tail选择List()**中提到的所有值
范例

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

Explanation

zbwhf8kr

zbwhf8kr8#

准备一个列出所有需求特性的列表,然后使用带 * 的Spark内置函数,参考如下所示。

lst = ["col1", "col2", "col3"]
result = df.select(*lst)

有时我们会收到错误:“分析异常:无法解析给定输入列的“col1””尝试将要素转换为字符串类型,如下所示:

from pyspark.sql.functions import lit
from pyspark.sql.types import StringType
for i in lst:
   if i not in df.columns:
      df = df.withColumn(i, lit(None).cast(StringType()))

最后,您将获得包含所需要素的数据集。

相关问题