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

合并两个类型为Array[字符串]的列到一个新的Array[字符串]列

卜方伟
2023-03-14

Spark SQLDataFrame中有两列,每列中的每个条目都是字符串数组。

val  ngramDataFrame = Seq(
  (Seq("curious", "bought", "20"), Seq("iwa", "was", "asj"))
).toDF("filtered_words", "ngrams_array")

我想合并每行中的数组,使一个新的列中的单个数组,我的代码如下:

def concat_array(firstarray: Array[String], 
                 secondarray: Array[String]) : Array[String] = 
                                     { (firstarray ++ secondarray).toArray }
val concatUDF = udf(concat_array _)
val concatFrame = ngramDataFrame.withColumn("full_array", concatUDF($"filtered_words", $"ngrams_array"))

我可以成功地在两个数组上使用concat_array函数。但是当我运行上述代码时,我得到以下异常

组织。阿帕奇。火花SparkException:作业因阶段失败而中止:阶段16.0中的任务0失败1次,最近的失败:阶段16.0中的任务0.0丢失(TID 12,localhost):org。阿帕奇。火花SparkException:无法执行用户定义的函数(anonfun$1:(数组,数组)=

共有2个答案

佴英奕
2023-03-14

Arjun您创建的udf中有一个错误。传递数组类型列时。数据类型不是数组[String],而是WrappedArray[String]。下面我将粘贴修改后的udf和输出。

val SparkCtxt = new SparkContext(sparkConf)

val sqlContext = new SQLContext(SparkCtxt)

import sqlContext.implicits

import org.apache.spark.sql.functions._
val temp=SparkCtxt.parallelize(Seq(Row(Array("String1","String2"),Array("String3","String4"))))
val df= sqlContext.createDataFrame(temp,
  StructType(List(
    StructField("Col1",ArrayType(StringType),true),
    StructField("Col2",ArrayType(StringType),true)
  )
  )    )

def concat_array(firstarray: mutable.WrappedArray[String],
                 secondarray: mutable.WrappedArray[String]) : mutable.WrappedArray[String] =
{
 (firstarray ++ secondarray)
}
val concatUDF = udf(concat_array _)
val df2=df.withColumn("udftest",concatUDF(df.col("Col1"), df.col("Col2")))
df2.select("udftest").foreach(each=>{println("***********")
println(each(0))})
df2.show(true)

输出:

+------------------+------------------+--------------------+
|              Col1|              Col2|             udftest|
+------------------+------------------+--------------------+
|[String1, String2]|[String3, String4]|[String1, String2...|
+------------------+------------------+--------------------+

WrappedArray(String1、String2、String3、String4)

孙阳旭
2023-03-14

在Spark 2.4或更高版本中,您可以使用concat(如果您想保留副本):

ngramDataFrame.withColumn(
  "full_array", concat($"filtered_words", $"ngrams_array")
).show
+--------------------+---------------+--------------------+
|      filtered_words|   ngrams_array|          full_array|
+--------------------+---------------+--------------------+
|[curious, bought,...|[iwa, was, asj]|[curious, bought,...|
+--------------------+---------------+--------------------+

或者array_union(如果您想删除重复项):

ngramDataFrame.withColumn(
  "full_array",
   array_union($"filtered_words", $"ngrams_array")
)

例如,这些函数也可以由其他高阶函数组成

ngramDataFrame.withColumn(
   "full_array",
   flatten(array($"filtered_words", $"ngrams_array"))
)

有重复的,还有

ngramDataFrame.withColumn(
   "full_array",
   array_distinct(flatten(array($"filtered_words", $"ngrams_array")))
)

没有

另外,在处理ArrayType列时,不应使用WrappedArray。相反,您应该期望得到保证的接口,即Seq。因此,udf应该使用具有以下签名的函数:

(Seq[String], Seq[String]) => Seq[String]

详情请参阅SQL编程指南。

 类似资料:
  • 问题内容: 我有这串 如何将此字符串拆分为每个子字符串包含2个字符的子字符串?我很困惑,因为我找不到分隔符来分隔它们。 问题答案:

  • 我想做一个名为句子的字符串,包含“你好,世界,你好吗?”

  • 问题内容: 假设我们有类似的东西: 我想将“ someText”替换为其他内容。考虑到我不知道someText可能是什么(任何字符串)并且我所知道的是它将被&firstString =和&endString =包围的事实,最佳方法是什么? 编辑:对不起,看起来这还不够清楚。我不知道“ someText”可能是什么,我仅有的信息是它将位于&firstString =和&endString =之间 我

  • 我对任何编程都非常陌生,所以请原谅我的无知,因为我不知道如何做一些看起来很简单的事情。 我所要做的就是获取任何字符串数组(称之为名称),比如: 并将其从列表中删除,并将其转换为字符串: 我似乎无法理解这一点,也找不到类似的帖子。

  • 问题内容: 例如,假设我有一个字符串,如下所示: 可以从该字符串中提取什么Go代码?我对Go还是比较陌生。任何帮助是极大的赞赏! 问题答案: 有很多方法可以拆分所有编程语言中的字符串。 由于我不知道您的特别要求,因此提供了一种示例方法,可从示例中获取所需的输出。 在上面的代码中,您从字符串的左侧和右侧进行了修剪。 正如我所说的,有数百种拆分特定字符串的方法,但这只是使您入门的一个示例。 希望对您有

  • 我试着比较两个字符串的字符 String string1=“ABC” 这里举个例子,如果我们一起比较字符串,在索引“1”中的字符串“B”中的索引0中可以找到字符串“A”,所以通过比较字符串,我应该得到一个数字01221,我知道在java中它有,,但我想不出如何实现这一点