繁体   English   中英

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

[英]How to get the name of a Spark Column as String?

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

df
.select(round($"x",2).as("x"))

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

def roundKeepName(c:Column,scale:Int) = round(c,scale).as(c.name)

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

 def roundKeepName(c:ColumnName,scale:Int) = round(c,scale).as(c.string.name)

但是我怎么能用Column (如果我使用col("x")而不是$"x"

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

def roundKeepname(c:Column,scale:Int) = round(c,scale).as(c.toString)

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

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

它有效:

scala> spark.range(2).select(roundKeepname('id, 2)).show
+---+
| id|
+---+
|  0|
|  1|
+---+  

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

def roundKeepName(columnName:String, scale:Int) = 
    round(col(columnName),scale).as(columnName)

更新:

使用 BlueSheepToken 给出的解决方法,这里是假设您拥有所有“双”列的动态方法。

scala> val df = Seq((1.22,4.34,8.93),(3.44,12.66,17.44),(5.66,9.35,6.54)).toDF("x","y","z")
df: org.apache.spark.sql.DataFrame = [x: double, y: double ... 1 more field]

scala> df.show
+----+-----+-----+
|   x|    y|    z|
+----+-----+-----+
|1.22| 4.34| 8.93|
|3.44|12.66|17.44|
|5.66| 9.35| 6.54|
+----+-----+-----+


scala>  df.columns.foldLeft(df)( (acc,p)  => (acc.withColumn(p+"_t",round(col(p),1)).drop(p).withColumnRenamed(p+"_t",p))).show
+---+----+----+
|  x|   y|   z|
+---+----+----+
|1.2| 4.3| 8.9|
|3.4|12.7|17.4|
|5.7| 9.4| 6.5|
+---+----+----+


scala>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM