我很好奇为什么这不能在Spark Scala的数据框架上工作:
df.withColumn("answer", locate(df("search_string"), col("hit_songs"), pos=1))
它与UDF一起工作,但不是上面所说的那样。Col和String方面。看起来很尴尬,缺乏方面。例如,如何将列转换为字符串以传递给需要字符串的定位。
df("search_string")
允许生成字符串是我的理解。
但是得到的错误是:
command-679436134936072:15: error: type mismatch;
found : org.apache.spark.sql.Column
required: String
df.withColumn("answer", locate(df("search_string"), col("hit_songs"), pos=1))
了解问题所在
我不确定您使用的是哪个版本的Spark,但是locate
方法在Spark 3.3.1(当前最新版本)和Spark 2.4.5(在我本地运行的Spark shell上运行的版本)上都具有以下功能签名。
函数签名如下:
def locate(substr: String, str: Column, pos: Int): Column
所以substr
不能是Column
,它必须是String
。在您的情况下,您使用df("search_string")
。这实际上调用apply
方法,函数签名如下:
def apply(colName: String): Column
所以你有一个问题是有道理的,因为locate
函数需要一个String
。
试图修复您的问题
如果我理解正确的话,您希望能够在没有udf的情况下从字符串的一列内的另一列中定位子字符串。您可以在Dataset
上使用map
来做到这一点。像这样:
import spark.implicits._
case class MyTest (A:String, B: String)
val df = Seq(
MyTest("with", "potatoes with meat"),
MyTest("with", "pasta with cream"),
MyTest("food", "tasty food"),
MyTest("notInThere", "don't forget some nice drinks")
).toDF("A", "B").as[MyTest]
val output = df.map{
case MyTest(a,b) => (a, b, b indexOf a)
}
output.show(false)
+----------+-----------------------------+---+
|_1 |_2 |_3 |
+----------+-----------------------------+---+
|with |potatoes with meat |9 |
|with |pasta with cream |6 |
|food |tasty food |6 |
|notInThere|don't forget some nice drinks|-1 |
+----------+-----------------------------+---+
一旦你进入了强类型Dataset
的map
操作,你就可以使用Scala语言了。
希望这对你有帮助!