Câu trả lời:
Với SQL thô, bạn có thể sử dụng CONCAT
:
Trong Python
df = sqlContext.createDataFrame([("foo", 1), ("bar", 2)], ("k", "v"))
df.registerTempTable("df")
sqlContext.sql("SELECT CONCAT(k, ' ', v) FROM df")
Ở 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")
Kể từ Spark 1.5.0, bạn có thể sử dụng concat
chức năng với API DataFrame:
Trong Python:
from pyspark.sql.functions import concat, col, lit
df.select(concat(col("k"), lit(" "), col("v")))
Trong Scala:
import org.apache.spark.sql.functions.{concat, lit}
df.select(concat($"k", lit(" "), $"v"))
Cũng có một concat_ws
hàm lấy dấu phân tách chuỗi làm đối số đầu tiên.
Đây là cách bạn có thể đặt tên tùy chỉnh
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()
cho,
+--------+--------+
|colname1|colname2|
+--------+--------+
| row11| row12|
| row21| row22|
+--------+--------+
tạo cột mới bằng cách nối:
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|
+--------+--------+-------------+
Một tùy chọn để nối các cột chuỗi trong Spark Scala đang sử dụng concat
.
Nó là cần thiết để kiểm tra các giá trị null . Bởi vì nếu một trong các cột là null, kết quả sẽ là null ngay cả khi một trong các cột khác có thông tin.
Sử dụng concat
và 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"))))
Sử dụng concat
và select
:
val newDf = df.selectExpr("concat(nvl(COL1, ''), nvl(COL2, '')) as NEW_COLUMN")
Với cả hai cách tiếp cận, bạn sẽ có NEW_COLUMN mà giá trị là sự ghép nối của các cột: COL1 và COL2 từ df ban đầu của bạn.
concat_ws
thay thế concat
, bạn có thể tránh kiểm tra NULL.
Nếu bạn muốn làm điều đó bằng DF, bạn có thể sử dụng udf để thêm một cột mới dựa trên các cột hiện có.
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()
Từ Spark 2.3 ( SPARK-22771 ) Spark SQL hỗ trợ toán tử nối ||
.
Ví dụ;
val df = spark.sql("select _c1 || _c2 as concat_column from <table_name>")
Đây là một cách khác để làm điều này cho 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 trở lên
Nối nhiều cột đầu vào với nhau thành một cột duy nhất. Hàm hoạt động với chuỗi, cột nhị phân và mảng tương thích.
Ví dụ: new_df = df.select(concat(df.a, df.b, df.c))
v1.5 trở lên
Tương tự như concat
but sử dụng dấu phân tách được chỉ định.
Ví dụ: new_df = df.select(concat_ws('-', df.col1, df.col2))
v2.4 và cao hơn
Được sử dụng để kết hợp các bản đồ, trả về kết hợp của tất cả các bản đồ đã cho.
Ví dụ: new_df = df.select(map_concat("map1", "map2"))
Sử dụng toán tử concat chuỗi ( ||
):
v2.3 và cao hơn
Ví dụ: df = spark.sql("select col_a || col_b || col_c as abc from table_x")
Tham khảo: Spark sql doc
Trong Spark 2.3.0, bạn có thể làm:
spark.sql( """ select '1' || column_a from table_a """)
Trong Java, bạn có thể thực hiện việc này để nối nhiều cột. Mã mẫu là để cung cấp cho bạn một kịch bản và cách sử dụng nó để bạn hiểu rõ hơn.
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ạn mã trên đã nối col1, col2, col3 được phân tách bằng "_" để tạo cột có tên "concatenatedCol".
Chúng tôi có cú pháp java tương ứng với quy trình dưới đây không
val dfResults = dfSource.select(concat_ws(",",dfSource.columns.map(c => col(c)): _*))
Một cách khác để làm điều đó trong pySpark bằng cách sử dụng 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'))
Thật vậy, có một số trừu tượng sẵn có đẹp mắt để bạn thực hiện việc nối mà không cần phải triển khai một hàm tùy chỉnh. Vì bạn đã đề cập đến Spark SQL, nên tôi đoán bạn đang cố chuyển nó dưới dạng lệnh khai báo thông qua spark.sql (). Nếu vậy, bạn có thể thực hiện theo cách chuyển tiếp lệnh SQL như:
SELECT CONCAT(col1, '<delimiter>', col2, ...) AS concat_column_name FROM <table_name>;
Ngoài ra, từ Spark 2.3.0, bạn có thể sử dụng các lệnh trong dòng với:
SELECT col1 || col2 AS concat_column_name FROM <table_name>;
Trong đó, là dấu phân cách ưa thích của bạn (cũng có thể là không gian trống) và là bảng tạm thời hoặc vĩnh viễn mà bạn đang cố gắng đọc.
Chúng ta cũng có thể đơn giản sử dụng SelectExpr. df1.selectExpr ("*", "upper (_2 || _3) as new")
lit
tạo một cột_