Risposte:
Con raw SQL puoi usare CONCAT
:
In Python
df = sqlContext.createDataFrame([("foo", 1), ("bar", 2)], ("k", "v"))
df.registerTempTable("df")
sqlContext.sql("SELECT CONCAT(k, ' ', v) FROM df")
In 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")
A partire da Spark 1.5.0 è possibile utilizzare la concat
funzione con l'API DataFrame:
In Python:
from pyspark.sql.functions import concat, col, lit
df.select(concat(col("k"), lit(" "), col("v")))
In Scala:
import org.apache.spark.sql.functions.{concat, lit}
df.select(concat($"k", lit(" "), $"v"))
C'è anche una concat_ws
funzione che accetta un separatore di stringa come primo argomento.
Ecco come puoi creare nomi personalizzati
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|
+--------+--------+
crea una nuova colonna concatenando:
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|
+--------+--------+-------------+
Un'opzione per concatenare le colonne di stringhe in Spark Scala sta usando concat
.
È necessario verificare la presenza di valori nulli . Perché se una delle colonne è nulla, il risultato sarà nullo anche se una delle altre colonne ha informazioni.
Utilizzando 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"))))
Utilizzando concat
e select
:
val newDf = df.selectExpr("concat(nvl(COL1, ''), nvl(COL2, '')) as NEW_COLUMN")
Con entrambi gli approcci avrai un NEW_COLUMN il cui valore è una concatenazione delle colonne: COL1 e COL2 dal tuo df originale.
concat_ws
posto di concat
, puoi evitare di verificare la presenza di NULL.
Se vuoi farlo usando DF, puoi usare un udf per aggiungere una nuova colonna basata su colonne esistenti.
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()
Da Spark 2.3 ( SPARK-22771 ) Spark SQL supporta l'operatore di concatenazione ||
.
Per esempio;
val df = spark.sql("select _c1 || _c2 as concat_column from <table_name>")
Ecco un altro modo per farlo per 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|
+------------+
v1.5 e successive
Concatena più colonne di input insieme in una singola colonna. La funzione funziona con stringhe, colonne di array binari e compatibili.
Per esempio: new_df = df.select(concat(df.a, df.b, df.c))
v1.5 e successive
Simile a concat
ma utilizza il separatore specificato.
Per esempio: new_df = df.select(concat_ws('-', df.col1, df.col2))
v2.4 e versioni successive
Usato per concatenare mappe, restituisce l'unione di tutte le mappe date.
Per esempio: new_df = df.select(map_concat("map1", "map2"))
Utilizzando l'operatore di concatenazione di stringhe ( ||
):
v2.3 e versioni successive
Per esempio: df = spark.sql("select col_a || col_b || col_c as abc from table_x")
Riferimento: Spark sql doc
In Spark 2.3.0, puoi fare:
spark.sql( """ select '1' || column_a from table_a """)
In Java puoi farlo per concatenare più colonne. Il codice di esempio serve a fornire uno scenario e come usarlo per una migliore comprensione.
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;
}
}
Il codice sopra ha concatenato col1, col2, col3 separato da "_" per creare una colonna con il nome "concatenatedCol".
Abbiamo la sintassi java corrispondente al processo seguente
val dfResults = dfSource.select(concat_ws(",",dfSource.columns.map(c => col(c)): _*))
Un altro modo per farlo in pySpark usando 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'))
In effetti, ci sono alcune bellissime astrazioni incorporate per realizzare la tua concatenazione senza la necessità di implementare una funzione personalizzata. Dato che hai menzionato Spark SQL, suppongo che tu stia cercando di passarlo come comando dichiarativo tramite spark.sql (). In tal caso, puoi eseguire in modo diretto passando il comando SQL come:
SELECT CONCAT(col1, '<delimiter>', col2, ...) AS concat_column_name FROM <table_name>;
Inoltre, da Spark 2.3.0, puoi utilizzare comandi in righe con:
SELECT col1 || col2 AS concat_column_name FROM <table_name>;
In cui, è il tuo delimitatore preferito (può essere anche uno spazio vuoto) ed è la tabella temporanea o permanente da cui stai cercando di leggere.
Possiamo anche usare semplicemente SelectExpr. df1.selectExpr ("*", "upper (_2 || _3) come nuovo")
lit
crea una colonna di_