我想写一种方法来舍入一个数字列而不做类似的事情:
df
.select(round($"x",2).as("x"))
因此,我需要有一个可重复使用的column-expression,例如:
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"
来生成)
答案 0 :(得分:1)
不确定问题是否真的得到了回答。您的函数可以这样实现(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|
+---+
答案 1 :(得分:-1)
更新:
使用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>