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

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次の列を作成します_
ミュオン2017

34

Spark Scalaで文字列列を連結する1つのオプションは、を使用することconcatです。

null値チェックする必要があります。列の1つがnullの場合、他の列の1つに情報がある場合でも結果はnullになるためです。

使用する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"))))

使用するconcatselect

val newDf = df.selectExpr("concat(nvl(COL1, ''), nvl(COL2, '')) as NEW_COLUMN")

どちらのアプローチでも、列の連結であるNEW_COLUMNが得られます。元のdfのCOL1およびCOL2です。


1
pysparkでメソッドを試しましたが、「colはColumnである必要があります」という警告が出て機能しませんでした。
サムソン

@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

データフレームの列の数または名前がわからない場合の推奨事項を次に示します。

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

4

concat(* cols)

v1.5以降

複数の入力列を1つの列に連結します。この関数は、文字列、バイナリ、互換性のある配列列で機能します。

例えば: 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 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

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

ここで、は優先する区切り文字(空のスペースでもかまいません)であり、読み取り元の一時テーブルまたは永続テーブルです。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.