Відповіді:
З необробленим SQL ви можете використовувати CONCAT
:
У Python
df = sqlContext.createDataFrame([("foo", 1), ("bar", 2)], ("k", "v"))
df.registerTempTable("df")
sqlContext.sql("SELECT CONCAT(k, ' ', v) FROM df")
У Скалі
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")
З Spark 1.5.0 ви можете використовувати concat
функцію з API DataFrame:
На Python:
from pyspark.sql.functions import concat, col, lit
df.select(concat(col("k"), lit(" "), col("v")))
У Scala:
import org.apache.spark.sql.functions.{concat, lit}
df.select(concat($"k", lit(" "), $"v"))
Існує також concat_ws
функція, яка приймає роздільник рядків як перший аргумент.
Ось як можна виконати власні імена
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()
дає,
+--------+--------+
|colname1|colname2|
+--------+--------+
| row11| row12|
| row21| row22|
+--------+--------+
створити новий стовпець шляхом об'єднання:
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|
+--------+--------+-------------+
Використовується один варіант об'єднання стовпчастих рядків у Spark Scala concat
.
Необхідно перевірити нульові значення . Тому що якщо один з стовпців є нульовим, результат буде нульовим, навіть якщо в одному з інших стовпців є інформація.
Використання concat
та 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"))))
Використання concat
та select
:
val newDf = df.selectExpr("concat(nvl(COL1, ''), nvl(COL2, '')) as NEW_COLUMN")
З обома підходами ви матимете NEW_COLUMN, значення якого є конкатенацією стовпців: COL1 та COL2 з початкового df.
concat_ws
замість concat
, ви можете уникнути перевірки на NULL.
Якщо ви хочете зробити це за допомогою DF, ви можете використовувати udf, щоб додати новий стовпчик на основі наявних стовпців.
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()
Від Spark 2.3 ( SPARK-22771 ) Spark SQL підтримує оператор конкатенації ||
.
Наприклад;
val df = spark.sql("select _c1 || _c2 as concat_column from <table_name>")
Ось ще один спосіб зробити це для 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 і вище
Об’єднує кілька вхідних стовпців разом в одну колонку. Функція працює з рядками, бінарними та сумісними стовпцями масивів.
Наприклад: new_df = df.select(concat(df.a, df.b, df.c))
v1.5 і вище
Аналогічно, concat
але використовує вказаний роздільник.
Наприклад: new_df = df.select(concat_ws('-', df.col1, df.col2))
v2.4 і вище
Використовується для стиснення карт, повертає об'єднання всіх поданих карт.
Наприклад: new_df = df.select(map_concat("map1", "map2"))
Використання оператора string concat ( ||
):
v2.3 і вище
Наприклад: df = spark.sql("select col_a || col_b || col_c as abc from table_x")
Довідка: Spark sql doc
На Java ви можете зробити це для об'єднання декількох стовпців. Зразок коду полягає у наданні вам сценарію та способів його використання для кращого розуміння.
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;
}
}
Вищенаведений код об'єднав col1, col2, col3, відокремлений символом "_" для створення стовпця з назвою "concatenizedCol".
Чи є у нас синтаксис Java, відповідний наведеному нижче процесу
val dfResults = dfSource.select(concat_ws(",",dfSource.columns.map(c => col(c)): _*))
Ще один спосіб зробити це в pySpark за допомогою 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'))
Дійсно, для вас є кілька прекрасних вбудованих абстракцій, щоб здійснити конкатенацію без необхідності впровадження спеціальної функції. Оскільки ви згадали Spark SQL, тож я здогадуюсь, що ви намагаєтесь передати його як декларативну команду через spark.sql (). Якщо так, ви можете виконати прямим способом, передаючи команду SQL на зразок:
SELECT CONCAT(col1, '<delimiter>', col2, ...) AS concat_column_name FROM <table_name>;
Також з Spark 2.3.0 ви можете використовувати команди в рядках з:
SELECT col1 || col2 AS concat_column_name FROM <table_name>;
При цьому - ваш кращий роздільник (може бути і порожній простір) і є тимчасовою або постійною таблицею, з якої ви намагаєтесь прочитати.
Ми можемо просто використовувати SelectExpr. df1.selectExpr ("*", "верхній (_2 || _3) як новий")
lit
створює колонку_