Nối các cột trong Apache Spark DataFrame


Câu trả lời:


175

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 concatchứ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_wshàm lấy dấu phân tách chuỗi làm đối số đầu tiên.


46

Đâ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|
+--------+--------+-------------+

4
littạo một cột_
muon

34

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 concatwithColumn:

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 concatselect:

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.


1
Tôi đã thử phương pháp của bạn trong pyspark nhưng nó không hoạt động, cảnh báo "col should be Column".
Samson

@Samson xin lỗi, tôi chỉ kiểm tra API Scala
Ignacio Alorre

3
@IgnacioAlorre Nếu bạn đang sử dụng concat_wsthay thế concat, bạn có thể tránh kiểm tra NULL.
Aswath K ngày

18

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()

12

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>")

10

Đâ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|
+------------+

7

Đây là một gợi ý khi bạn không biết số lượng hoặc tên của các cột trong Dataframe.

val dfResults = dfSource.select(concat_ws(",",dfSource.columns.map(c => col(c)): _*))

4

concat (* cols)

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))


concat_ws (sep, * cols)

v1.5 trở lên

Tương tự như concatbut sử dụng dấu phân tách được chỉ định.

Ví dụ: new_df = df.select(concat_ws('-', df.col1, df.col2))


map_concat (* cols)

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


2

Trong Spark 2.3.0, bạn có thể làm:

spark.sql( """ select '1' || column_a from table_a """)

1

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".


1

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)): _*))

0

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'))

0

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.


0

Chúng ta cũng có thể đơn giản sử dụng SelectExpr. df1.selectExpr ("*", "upper (_2 || _3) as new")

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.