[英]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.