Merge two spark sql columns of type Array[string] into a new Array[string] column

前端 未结 2 1673
旧巷少年郎
旧巷少年郎 2021-01-05 15:01

I have two columns in a Spark SQL DataFrame with each entry in either column as an array of strings.

val  ngramDataFrame = Seq(
  (Seq(\"curiou         


        
相关标签:
2条回答
  • 2021-01-05 15:25

    Arjun there is an error in the udf you had created.when you are passing the array type columns .data type is not Array[String] it is WrappedArray[String].below i am pasting the modified udf along with output.

    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)
    

    OUTPUT:

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

    WrappedArray(String1, String2, String3, String4)

    0 讨论(0)
  • 2021-01-05 15:38

    In Spark 2.4 or later you can use concat (if you want to keep duplicates):

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

    or array_union (if you want to drop duplicates):

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

    These can be also composed from the other higher order functions, for example

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

    with duplicates, and

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

    without.

    On a side note, you shouldn't use WrappedArray when working with ArrayType columns. Instead you should expect the guaranteed interface, which is Seq. So the udf should use function with following signature:

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

    Please refer to SQL Programming Guide for details.

    0 讨论(0)
提交回复
热议问题