我有以下模仿枚举的对象:
object ColumnNames {
val JobSeekerID = "JobSeekerID"
val JobID = "JobID"
val Date = "Date"
val BehaviorType = "BehaviorType"
}
然后我想按列对DF进行分组。以下内容无法编译:
userJobBehaviourDF.groupBy($(ColumnNames.JobSeekerID))
如果我将其更改为
userJobBehaviourDF.groupBy($"JobSeekerID")
有效。
如何一起使用$
和ColumnNames.JobSeekerID
来执行此操作?
答案 0 :(得分:2)
$
是一个名为string interpolator的Scala功能。
从Scala 2.10.0开始,Scala提供了一种从数据创建字符串的新机制:String Interpolation。 String Interpolation允许用户直接在已处理的字符串文字中嵌入变量引用。
Spark将Spark SQL中的字符串插补器用于convert $"col name" into a column。
scala> spark.version
res0: String = 2.3.0-SNAPSHOT
scala> :type $"hello"
org.apache.spark.sql.ColumnName
ColumnName
类型是Column
类型的子类型,这就是为什么您可以使用$
- 前缀字符串作为列引用,其中Column
类型的值是预期的。
import org.apache.spark.sql.Column
val c: Column = $"columnName"
scala> :type c
org.apache.spark.sql.Column
如何使用$和ColumnNames.JobSeekerID一起执行此操作?
你不能。
您应该直接使用Column
将列名称(在“枚举器”中)映射到$
类型(这需要将其类型更改为Column
)或使用{{ <} {}需要Columns
时才会运行{}}或col。
col(colName:String):Column 根据给定的列名返回一列。
column(colName:String):Column 根据给定的列名返回一个列。
$
其他地方有趣的是Spark MLlib使用$
- ML参数的前缀字符串,但在这种情况下$
column。
protected final def $[T](param: Param[T]): T = getOrDefault(param)
还值得一提的是,is just a regular method中使用了$
字符串插补器来创建可用于测试或Spark SQL内部探索的逻辑UnresolvedAttributes
。
import org.apache.spark.sql.catalyst.dsl.expressions._
scala> :type $"hello"
org.apache.spark.sql.catalyst.analysis.UnresolvedAttribute
字符串插值器功能在编译时工作(被解析为正确的值),因此它是一个字符串文字或者它将失败。
$
类似于s
Catalyst DSL:
将
s
预先添加到任何字符串文字允许直接在字符串中使用变量。
Scala提供了三种开箱即用的字符串插值方法:s
,f
和raw
,您可以像Spark一样编写自己的插值器。
答案 1 :(得分:0)
您只能将$
与字符串文字(值)一起使用如果您想使用ColumnNames
,可以执行以下操作
userJobBehaviourDF.groupBy(userJobBehaviourDF(ColumnNames.JobSeekerID))
userJobBehaviourDF.groupBy(col(ColumnNames.JobSeekerID))
从Spark Docs for Column开始,以下是表示列的不同方法:
df("columnName") // On a specific `df` DataFrame. col("columnName") // A generic column no yet associated with a DataFrame. col("columnName.field") // Extracting a struct field col("`a.column.with.dots`") // Escape `.` in column names. $"columnName" // Scala short hand for a named column.
希望这有帮助!