Apache Spark DataFrame의 열 연결


답변:


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부터 concatDataFrame API와 함께 함수를 사용할 수 있습니다 .

  • 파이썬에서 :

    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

Spark Scala에서 문자열 열을 연결하는 한 가지 옵션은 concat.

null 값확인해야합니다 . 열 중 하나가 널이면 다른 열 중 하나에 정보가 있어도 결과는 널이됩니다.

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

두 가지 접근 방식을 사용하면 값이 원래 df의 COL1 및 COL2 열의 연결 인 NEW_COLUMN을 갖게됩니다.


1
pyspark에서 귀하의 방법을 시도했지만 작동하지 않고 "col should be Column"이라고 경고합니다.
Samson

죄송 @Samson, 난 단지 스칼라 API 검사
이그나시오 Alorre에게

3
@IgnacioAlorre concat_ws대신을 사용 하는 경우 concatNULL 검사를 피할 수 있습니다.
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 (sep, * 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"))


문자열 연결 연산자 ( ||) 사용 :

v2.3 이상

예 : df = spark.sql("select col_a || col_b || col_c as abc from table_x")

참조 : Spark SQL 문서


2

Spark 2.3.0에서는 다음을 수행 할 수 있습니다.

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

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

sqlContext를 사용하여 pySpark에서 수행하는 또 다른 방법 ...

#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>;

여기서는 선호하는 구분 기호 (빈 공간 일 수도 있음)이며 읽으려는 임시 또는 영구 테이블입니다.


0

SelectExpr도 간단하게 사용할 수 있습니다. df1.selectExpr ( "*", "upper (_2 || _3) as new")

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.