Concatenate columns in Apache Spark DataFrame

Como combinamos duas colunas num DataFrame Apache? Existe alguma função em Spark SQL que possamos usar?

Author: Community, 2015-07-16

10 answers

Com SQL raw pode usar CONCAT:

  • Em Python

    df = sqlContext.createDataFrame([("foo", 1), ("bar", 2)], ("k", "v"))
    df.registerTempTable("df")
    sqlContext.sql("SELECT CONCAT(k, ' ',  v) FROM df")
    
  • Em Scala

    import sqlContext.implicits._
    
    val df = sc.parallelize(Seq(("foo", 1), ("bar", 2))).toDF("k", "v")
    df.registerTempTable("df")
    sqlContext.sql("SELECT CONCAT(k, ' ',  v) FROM df")
    

Desde a Spark 1, 5, 0 pode usar a função concat com a API DataFrame:

  • Em Python:

    from pyspark.sql.functions import concat, col, lit
    
    df.select(concat(col("k"), lit(" "), col("v")))
    
  • Em Scala:

    import org.apache.spark.sql.functions.{concat, lit}
    
    df.select(concat($"k", lit(" "), $"v"))
    

Existe também a função concat_ws que toma um separador de cadeias como o primeiro argumento.

 97
Author: zero323, 2016-02-22 20:02:19

Aqui está como você pode fazer nomes personalizados

import pyspark
from pyspark.sql import functions as sf
sc = pyspark.SparkContext()
sqlc = pyspark.SQLContext(sc)
df = sqlc.createDataFrame([('row11','row12'), ('row21','row22')], ['colname1', 'colname2'])
df.show()

Dá,

+--------+--------+
|colname1|colname2|
+--------+--------+
|   row11|   row12|
|   row21|   row22|
+--------+--------+

Criar uma nova coluna através da concatenação:

df = df.withColumn('joined_column', 
                    sf.concat(sf.col('colname1'),sf.lit('_'), sf.col('colname2')))
df.show()

+--------+--------+-------------+
|colname1|colname2|joined_column|
+--------+--------+-------------+
|   row11|   row12|  row11_row12|
|   row21|   row22|  row21_row22|
+--------+--------+-------------+
 16
Author: muon, 2017-09-06 15:51:03

Se o quiser fazer com DF, poderá usar um udf para adicionar uma nova coluna com base nas colunas existentes.

val sqlContext = new SQLContext(sc)
case class MyDf(col1: String, col2: String)

//here is our dataframe
val df = sqlContext.createDataFrame(sc.parallelize(
    Array(MyDf("A", "B"), MyDf("C", "D"), MyDf("E", "F"))
))

//Define a udf to concatenate two passed in string values
val getConcatenated = udf( (first: String, second: String) => { first + " " + second } )

//use withColumn method to add a new column called newColName
df.withColumn("newColName", getConcatenated($"col1", $"col2")).select("newColName", "col1", "col2").show()
 15
Author: Danish Shrestha, 2015-07-20 22:27:48

Aqui está uma sugestão para quando você não sabe o número ou nome das colunas no Dataframe.

val dfResults = dfSource.select(concat_ws(",",dfSource.columns.map(c => col(c)): _*))
 4
Author: wones0120, 2017-08-17 17:48:23
Aqui está outra maneira de fazer isto pela pyspark:
#import concat and lit functions from pyspark.sql.functions 
from pyspark.sql.functions import concat, lit

#Create your data frame
countryDF = sqlContext.createDataFrame([('Ethiopia',), ('Kenya',), ('Uganda',), ('Rwanda',)], ['East Africa'])

#Use select, concat, and lit functions to do the concatenation
personDF = countryDF.select(concat(countryDF['East Africa'], lit('n')).alias('East African'))

#Show the new data frame
personDF.show()

----------RESULT-------------------------

84
+------------+
|East African|
+------------+
|   Ethiopian|
|      Kenyan|
|     Ugandan|
|     Rwandan|
+------------+
 4
Author: Teddy Belay, 2017-09-06 15:51:16

Uma opção para concatenar colunas de cordas em Spark Scala está a usar concat.

É necessário verificar os valores nulos . Porque se uma das colunas for nula, o resultado será nulo mesmo que uma das colunas tenha informação.

Usando concat e withColumn:

val newDf =
  df.withColumn(
    "NEW_COLUMN",
    concat(
      when(col("COL1").isNotNull, col("COL1")).otherwise(lit("null")),
      when(col("COL2").isNotNull, col("COL2")).otherwise(lit("null"))))

Usando concat e select:

val newDf = df.selectExpr("concat(nvl(COL1, ''), nvl(COL2, '')) as NEW_COLUMN")

Com ambas as abordagens, terá uma coluna NEW_ column que o valor é uma concatenação das colunas: COL1 e COL2 do seu df original.

 4
Author: Ignacio Alorre, 2018-09-27 17:54:52

Em faísca 2.3.0, pode fazer:

spark.sql( """ select '1' || column_a from table_a """)
 1
Author: Charlie 木匠, 2018-03-12 20:24:29

Outra forma de o fazer em pySpark usando o sqlContext...

#Suppose we have a dataframe:
df = sqlContext.createDataFrame([('row1_1','row1_2')], ['colname1', 'colname2'])

# Now we can concatenate columns and assign the new column a name 
df = df.select(concat(df.colname1, df.colname2).alias('joined_colname'))
 0
Author: Gur, 2017-03-17 05:54:50

O contexto SQL Spark suporta o operador de concatenação ||. Por exemplo;

val df = sqlContext.sql("select _c1||_c2 as concat_column from <table_name>")

A minha versão de faísca 2.3.0

 -1
Author: Krishas, 2018-04-19 14:15:05

Em Java você pode fazer isso para concatenar várias colunas. O código de exemplo é fornecer-lhe um cenário e como usá-lo para melhor compreensão.

SparkSession spark = JavaSparkSessionSingleton.getInstance(rdd.context().getConf());
Dataset<Row> reducedInventory = spark.sql("select * from table_name")
                        .withColumn("concatenatedCol",
                                concat(col("col1"), lit("_"), col("col2"), lit("_"), col("col3")));


class JavaSparkSessionSingleton {
    private static transient SparkSession instance = null;

    public static SparkSession getInstance(SparkConf sparkConf) {
        if (instance == null) {
            instance = SparkSession.builder().config(sparkConf)
                    .getOrCreate();
        }
        return instance;
    }
}

O código acima concatenado col1, col2, col3 separado por " _ "para criar uma coluna com o nome"concentrado".

 -1
Author: wandermonk, 2018-04-19 18:19:52