เชื่อมต่อคอลัมน์ใน Apache Spark DataFrame


117

เราจะเชื่อมสองคอลัมน์ใน Apache Spark DataFrame เข้าด้วยกันได้อย่างไร มีฟังก์ชันใดใน Spark SQL ที่เราสามารถใช้ได้หรือไม่?

คำตอบ:


175

ด้วย 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ฟังก์ชันกับ DataFrame API:

  • ใน 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ฟังก์ชันที่ใช้ตัวคั่นสตริงเป็นอาร์กิวเมนต์แรก


46

นี่คือวิธีตั้งชื่อแบบกำหนดเอง

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

4
litสร้างคอลัมน์ของ_
muon

34

ทางเลือกหนึ่งคอลัมน์สตริง concatenate ใน 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 เดิมของคุณ


1
ฉันลองใช้วิธีของคุณใน pyspark แล้ว แต่ไม่ได้ผลคำเตือน "col ควรเป็น Column"
Samson

@ Samson ขอโทษฉันตรวจสอบ Scala API เท่านั้น
Ignacio Alorre

3
@IgnacioAlorre หากคุณกำลังใช้concat_wsแทนการใช้concatคุณสามารถหลีกเลี่ยงการตรวจสอบค่า NULL ได้
Aswath K

18

ถ้าคุณต้องการทำโดยใช้ 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()

12

จาก Spark 2.3 ( SPARK-22771 ) Spark SQL ||สนับสนุนผู้ประกอบการ

ตัวอย่างเช่น;

val df = spark.sql("select _c1 || _c2 as concat_column from <table_name>")

10

นี่เป็นอีกวิธีหนึ่งในการทำสิ่งนี้สำหรับ 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

นี่คือคำแนะนำเมื่อคุณไม่ทราบหมายเลขหรือชื่อของคอลัมน์ใน Dataframe

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

4

concat (* cols)

v1.5 และสูงกว่า

เชื่อมคอลัมน์อินพุตหลายคอลัมน์เข้าด้วยกันเป็นคอลัมน์เดียว ฟังก์ชันทำงานร่วมกับสตริงไบนารีและคอลัมน์อาร์เรย์ที่เข้ากันได้

เช่น: new_df = df.select(concat(df.a, df.b, df.c))


concat_ws (กันยายน, * cols)

v1.5 และสูงกว่า

คล้ายกับconcatแต่ใช้ตัวคั่นที่ระบุ

เช่น: new_df = df.select(concat_ws('-', df.col1, df.col2))


map_concat (* cols)

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



1

ใน 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 แยกโดย "_" เพื่อสร้างคอลัมน์ที่มีชื่อ "concatenatedCol"


1

เรามีไวยากรณ์ java ที่สอดคล้องกับกระบวนการด้านล่างหรือไม่

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

0

อีกวิธีในการทำใน 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'))

0

อันที่จริงมีตัวย่อที่สวยงามในตัวเพื่อให้คุณสามารถเชื่อมต่อกันได้โดยไม่จำเป็นต้องใช้ฟังก์ชันที่กำหนดเอง เนื่องจากคุณพูดถึง 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>;

ซึ่งเป็นตัวคั่นที่คุณต้องการ (อาจเป็นพื้นที่ว่างก็ได้เช่นกัน) และเป็นตารางชั่วคราวหรือถาวรที่คุณพยายามอ่าน


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.