当前位置: 首页 > 知识库问答 >
问题:

在spark scala中将Array[seq[String]]传递给UDF

李法
2023-03-14

我刚到UDF的斯帕克。我也看过这里的回答

问题陈述:我正在尝试从数据帧列中查找模式匹配。

例如:数据帧

val df = Seq((1, Some("z")), (2, Some("abs,abc,dfg")),
             (3,Some("a,b,c,d,e,f,abs,abc,dfg"))).toDF("id", "text")

df.show()

+---+--------------------+
| id|                text|
+---+--------------------+
|  1|                   z|
|  2|         abs,abc,dfg|
|  3|a,b,c,d,e,f,abs,a...|
+---+--------------------+


df.filter($"text".contains("abs,abc,dfg")).count()
//returns 2 as abs exits in 2nd row and 3rd row

现在我想对列$text中的每一行进行模式匹配,并添加一个名为count的新列。

结果:

+---+--------------------+-----+
| id|                text|count|
+---+--------------------+-----+
|  1|                   z|    1|
|  2|         abs,abc,dfg|    2|
|  3|a,b,c,d,e,f,abs,a...|    1|
+---+--------------------+-----+

我试图定义一个udf,将$text列作为数组[Seq[String]传递。但是我不能得到我想要的。

到目前为止,我尝试过:

val txt = df.select("text").collect.map(_.toSeq.map(_.toString)) //convert column to Array[Seq[String]
val valsum = udf((txt:Array[Seq[String],pattern:String)=> {txt.count(_ == pattern) } )
df.withColumn("newCol", valsum( lit(txt) ,df(text)) )).show()

任何帮助都将不胜感激

共有1个答案

胡劲
2023-03-14

您必须知道文本列的所有元素,这可以使用collect_list,通过数据帧的所有组合为一个来完成。然后只需检查收集的数组中<code>text</code>列中的元素,并<code>计数</code>它们,如下代码所示。

import sqlContext.implicits._
import org.apache.spark.sql.functions._
import org.apache.spark.sql.expressions._

val df = Seq((1, Some("z")), (2, Some("abs,abc,dfg")),(3,Some("a,b,c,d,e,f,abs,abc,dfg"))).toDF("id", "text")

val valsum = udf((txt: String, array : mutable.WrappedArray[String])=> array.filter(element => element.contains(txt)).size)
df.withColumn("grouping", lit("g"))
  .withColumn("array", collect_list("text").over(Window.partitionBy("grouping")))
  .withColumn("count", valsum($"text", $"array"))
  .drop("grouping", "array")
  .show(false)

您应该有以下输出

+---+-----------------------+-----+
|id |text                   |count|
+---+-----------------------+-----+
|1  |z                      |1    |
|2  |abs,abc,dfg            |2    |
|3  |a,b,c,d,e,f,abs,abc,dfg|1    |
+---+-----------------------+-----+

我希望这是有帮助的。

 类似资料:
  • 我试图使用以下公式将Future[Seq[(String,String)]转换为Future[Seq[(String)]: 所以 sortedSeq 是 Future[Seq[(String, String)]] 但我一直得到错误: 我做错了什么?

  • 问题内容: 我正在尝试将字符串数组作为POST数据传递给PHP脚本,但是不确定该怎么做。 这是到目前为止我执行PHP脚本的代码: 我试图传递数组的地方: 调用PHP脚本: 以及相关的PHP脚本: 有任何想法吗?谢谢 ! 编辑 我正在尝试以下方法,但仍不满意: 这就是我所有的“错误报告” … 问题答案: 要将查询字符串中的数组传递给php,您应该添加到标识符并将每个项目都添加为单独的条目,因此这样的

  • 我试图将一个字符串和一个列表传递给pandas.isin()方法。下面是我的代码 这里的问题是,.isin([])对于字符串的每次迭代都很好,但是当我到达overall_months[-1]时,它是一个列表,您不能将列表传递到.isin([])语法中。我试过了,但不能删除双引号,因为我的理解是字符串是不可变的: 有什么最好的帮助来完成这件事吗?

  • 我在Scala的Spark数据框架中有一列,它是使用 我想将此列传递给UDF,以便进一步处理,以处理此聚合列中的一个索引。 当我将参数传递给我的UDF时: UDF-类型为Seq[Row]:val removeUnstableActivations:UserDefinedFunction=UDF((xyz:java.util.Date,def:Seq[Row]) 我收到错误: 我应该如何传递这些列,

  • 问题内容: 我的字符串中某些地方包含数字,并且我正尝试用其单词符号替换此数字(即3-> 3)。我有一个功能可以做到这一点。现在的问题是找到字符串中的数字,同时保持字符串的其余部分不变。为此,我选择使用该函数,该函数可以接受“ callable”。但是,传递给它的对象是内部对象,我不确定如何处理它。我的函数接受数字或其字符串表示形式。 我应该如何编写一些辅助函数,该函数可用于将调用与执行所需处理的函

  • 问题内容: 我试图将SharedPreferences首选项作为AsyncTask中doInBackground函数的参数传递。我已经给它传递了一个字符串(URL),所以我也需要将首选项也作为字符串传递。我可以简单地使用prefs.toString()将其转换为字符串吗? 这是我设置偏好的地方: 问题答案: 你不能,你不应该。您可以轻松地读取内部首选项,而无需将任何内容传递给方法,只需使用即可: