Comment concaténer deux colonnes dans un Apache Spark DataFrame? Existe-t-il une fonction que Spark SQL peut utiliser?
Avec le SQL brut, vous pouvez utiliser CONCAT
:
En python
df = sqlContext.createDataFrame([("foo", 1), ("bar", 2)], ("k", "v"))
df.registerTempTable("df")
sqlContext.sql("SELECT CONCAT(k, ' ', v) FROM df")
En 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")
Depuis Spark 1.5.0, vous pouvez utiliser la fonction concat
avec l’API DataFrame:
En Python:
from pyspark.sql.functions import concat, col, lit
df.select(concat(col("k"), lit(" "), col("v")))
En Scala:
import org.Apache.spark.sql.functions.{concat, lit}
df.select(concat($"k", lit(" "), $"v"))
Il existe également une fonction concat_ws
qui prend un premier séparateur de chaîne.
Voici comment vous pouvez nommer personnalisé
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()
donne,
+--------+--------+
|colname1|colname2|
+--------+--------+
| row11| row12|
| row21| row22|
+--------+--------+
créer une nouvelle colonne en concaténant:
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|
+--------+--------+-------------+
Si vous souhaitez utiliser DF, vous pouvez utiliser un fichier UDF pour ajouter une nouvelle colonne en fonction des colonnes existantes.
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()
Une option pour concaténer des colonnes de chaîne dans Spark Scala consiste à utiliser concat
.
Il est nécessaire de vérifier les valeurs nulles . Car si l'une des colonnes est nulle, le résultat le sera même si l'une des autres colonnes contient des informations.
Utiliser concat
et 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"))))
Utiliser concat
et select
:
val newDf = df.selectExpr("concat(nvl(COL1, ''), nvl(COL2, '')) as NEW_COLUMN")
Avec les deux approches, vous aurez un NEW_COLUMN dont la valeur est une concaténation des colonnes: COL1 et COL2 de votre df d'origine.
Voici une autre façon de faire cela pour 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|
+------------+
Voici une suggestion à suivre lorsque vous ne connaissez pas le numéro ou le nom des colonnes du Dataframe.
val dfResults = dfSource.select(concat_ws(",",dfSource.columns.map(c => col(c)): _*))
À partir de Spark 2.3 ( SPARK-22771 ) Spark SQL prend en charge l'opérateur de concaténation ||
.
Par exemple;
val df = spark.sql("select _c1 || _c2 as concat_column from <table_name>")
Dans Spark 2.3.0, vous pouvez effectuer les tâches suivantes:
spark.sql( """ select '1' || column_a from table_a """)
En Java, vous pouvez faire cela pour concaténer plusieurs colonnes. L'exemple de code consiste à vous fournir un scénario et à vous en servir pour une meilleure compréhension.
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;
}
}
Le code ci-dessus concaténé col1, col2, col3 séparé par "_" pour créer une colonne avec le nom "concatenatedCol".
En effet, il existe de belles abstractions intégrées pour vous permettre d'accomplir votre concaténation sans avoir à implémenter une fonction personnalisée. Puisque vous avez mentionné Spark SQL, je suppose que vous essayez de le transmettre en tant que commande déclarative via spark.sql (). Si tel est le cas, vous pouvez accomplir directement en passant une commande SQL telle que: SELECT CONCAT(col1, '<delimiter>', col2, ...) AS concat_column_name FROM <table_name>;
De plus, à partir de Spark 2.3.0, vous pouvez utiliser des commandes alignées avec: SELECT col1 || col2 AS concat_column_name FROM <table_name>;
Où est votre séparateur préféré (peut-être aussi un espace vide) et la table temporaire ou permanente que vous essayez de lire.
Une autre façon de le faire dans pySpark en utilisant 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'))