如何获取 Spark 列的字符串名称?

Rap*_*oth 4 scala apache-spark

我想编写一种方法来舍入数字列,而不执行以下操作:

df
.select(round($"x",2).as("x"))
Run Code Online (Sandbox Code Playgroud)

因此我需要一个可重用的列表达式,例如:

def roundKeepName(c:Column,scale:Int) = round(c,scale).as(c.name)
Run Code Online (Sandbox Code Playgroud)

不幸的c.name是不存在,因此上面的代码无法编译。我找到了一个解决方案ColumName

 def roundKeepName(c:ColumnName,scale:Int) = round(c,scale).as(c.string.name)
Run Code Online (Sandbox Code Playgroud)

但是我该如何做到这一点Column(如果我使用col("x")而不是生成$"x"

Oli*_*Oli 5

不确定问题是否得到了真正的回答。您的函数可以这样实现(toString返回列的名称):

def roundKeepname(c:Column,scale:Int) = round(c,scale).as(c.toString)
Run Code Online (Sandbox Code Playgroud)

如果您不喜欢依赖 toString,这里有一个更强大的版本。您可以依赖底层表达式,将其转换为 NamedExpression 并获取其名称。

import org.apache.spark.sql.catalyst.expressions.NamedExpression
def roundKeepname(c:Column,scale:Int) = 
    c.expr.asInstanceOf[NamedExpression].name
Run Code Online (Sandbox Code Playgroud)

它有效:

scala> spark.range(2).select(roundKeepname('id, 2)).show
+---+
| id|
+---+
|  0|
|  1|
+---+  
Run Code Online (Sandbox Code Playgroud)

编辑 最后,如果您可以使用列的名称而不是 Column 对象,您可以更改函数的签名,这会产生更简单的实现:

def roundKeepName(columnName:String, scale:Int) = 
    round(col(columnName),scale).as(columnName)
Run Code Online (Sandbox Code Playgroud)