[英]Spark 1.6 apply function to column with dot in name/ How to properly escape colName
要将函数应用于Spark中的列,常见的方法(唯一的方法是?)似乎是
df.withColumn(colName, myUdf(df.col(colName))
很好,但我的名字中有圆点的列,要访问列,我需要用反引号“`”来转义名称
问题是:如果我使用该转义名称,.withColumn函数会创建一个带有转义名称的新列
df.printSchema
root
|-- raw.hourOfDay: long (nullable = false)
|-- raw.minOfDay: long (nullable = false)
|-- raw.dayOfWeek: long (nullable = false)
|-- raw.sensor2: long (nullable = false)
df = df.withColumn("raw.hourOfDay", df.col("raw.hourOfDay"))
org.apache.spark.sql.AnalysisException: Cannot resolve column name "raw.hourOfDay" among (raw.hourOfDay, raw.minOfDay, raw.dayOfWeek, raw.sensor2);
这工作:
df = df.withColumn("`raw.hourOfDay`", df.col("`raw.hourOfDay`"))
df: org.apache.spark.sql.DataFrame = [raw.hourOfDay: bigint, raw.minOfDay: bigint, raw.dayOfWeek: bigint, raw.sensor2: bigint, `raw.hourOfDay`: bigint]
scala> df.printSchema
root
|-- raw.hourOfDay: long (nullable = false)
|-- raw.minOfDay: long (nullable = false)
|-- raw.dayOfWeek: long (nullable = false)
|-- raw.sensor2: long (nullable = false)
|-- `raw.hourOfDay`: long (nullable = false)
但正如您所看到的,架构有一个新的转义列名称。
如果我执行上述操作并尝试删除带有转义名称的旧列,它将删除旧列,但在此之后,任何尝试访问新列的结果都会导致:
org.apache.spark.sql.AnalysisException: Cannot resolve column name "`raw.sensor2`" among (`raw.hourOfDay`, `raw.minOfDay`, `raw.dayOfWeek`, `raw.sensor2`);
就好像它现在将反引号理解为名称的标准而不是逃避字符。
那么如何在不改变名称的情况下用withColumn
'替换'我的旧列?
(PS:请注意我的列名是参数化的,所以我在名称上使用了一个循环。为清楚起见,我在这里使用了特定的字符串名称:转义序列看起来真的像“`”+ colName +“`”)
编辑:
现在我发现的唯一技巧就是:
for (t <- df.columns) {
if (t.contains(".")) {
df = df.withColumn("`" + t + "`", myUdf(df.col("`" + t + "`")))
df = df.drop(df.col("`" + t + "`"))
df = df.withColumnRenamed("`" + t + "`", t)
}
else {
df = df.withColumn(t, myUdf(df.col(t)))
}
}
我觉得不是很有效率......
编辑 :
文档状态:
def withColumn(colName: String, col: Column): DataFrame
Returns a new DataFrame by adding a column
or replacing the existing column that has the same name.
因此,替换列应该不是问题。 然而正如下面的@Glennie指出的那样,使用新名称可以正常工作,因此这可能是Spark 1.6中的一个错误
谢谢你的伎俩。
df = df.withColumn("`" + t + "`", myUdf(df.col("`" + t + "`")))
df = df.drop(df.col("`" + t + "`"))
df = df.withColumnRenamed("`" + t + "`", t)
它对我来说很好。 期待看到更好的解决方案。 只是提醒一下,我们也会遇到与'#'字符类似的问题。
我不相信你可以添加一个与现有列同名的列(为什么你呢?)。
df = df.withColumn("raw.hourOfDay", df.col("`raw.hourOfDay`"))
如你所指出的那样会失败,但不是因为名称没有被正确转义,而是因为名称与现有列相同。
df = df.withColumn("raw.hourOfDay_2", df.col("`raw.hourOfDay`"))
另一方面将评估就好了:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.