0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【トリビアのDelta Lake】#3 Pysparkで全行とも同じ値が入った列を新設したい

Last updated at Posted at 2022-04-01

Pysparkで、同じ値だけを各行に入れた列を新設したい

今回は少しマイナーなTipsかもしれませんが、意外と「あれどうやるんだっけ?」となることが多いので書いてみます。

今回も例によってサンプルデータを用意します。

sample_data = [{'name': 'Alice',"age": '2',}, 
               {'name': 'Bob',"age": '50'},
               {'name': 'Matilda',"age": '12'}]

df = spark.createDataFrame(sample_data)
df.show()

【結果】
+---+-------+
|age|   name|
+---+-------+
|  2|  Alice|
| 50|    Bob|
| 12|Matilda|
+---+-------+

ここに、birthplace(出身地)という列を新設しようと思います。
値となる地名は何でもいいですが、せっかく名前にマチルダを追加したのでここでは映画『レオン』に則って「NewYork」としましょうか。
3人とも、全員ニューヨーク出身として、NewYorkという値が各行に入った列を追加します。

litで値を囲むのがミソ

結論、こんな感じで書くことが出来ます!

from pyspark.sql.functions import lit
df_add_birthplace = (
    df
    .withColumn("birthplace",lit("NewYork"))
)
df_add_birthplace.show()

【結果】
+---+-------+----------+
|age|   name|birthplace|
+---+-------+----------+
|  2|  Alice|   NewYork|
| 50|    Bob|   NewYork|
| 12|Matilda|   NewYork|
+---+-------+----------+

列を追加するコマンドとして.withColumnがある、というのは割と有名ですよね。
ここでは

df.withColumn("新設するカラム名",lit("新設列に入れる値"))

といった文法になります。

想定されるユースケース:名前からメアドを生成

といっても、Pysparkで行うETL作業の中で、元データから必要なものだけに削ぐことはあっても追加する、ってことは経験上あまりないのかなと思っています。

そのなかでも、想定されるユースケースとしては、例えば「メールアドレスの生成」があるかなと思います!

sample_data = [{'name': 'Alice',"age": '2',}, 
               {'name': 'Bob',"age": '50'},
               {'name': 'Matilda',"age": '12'}]
df = spark.createDataFrame(sample_data)

#「mail_domain」列を追加する
from pyspark.sql.functions import lit
df_add_mail_domain = (
    df
    .withColumn("mail_domain",lit("@amail.com"))
)
df_add_mail_domain.show()

【結果】
+---+-------+-----------+
|age|   name|mail_domain|
+---+-------+-----------+
|  2|  Alice| @amail.com|
| 50|    Bob| @amail.com|
| 12|Matilda| @amail.com|
+---+-------+-----------+

そして、nameとmail_domainをconcatで結合すると、晴れてメールアドレスの出来上がりです!
(今回は架空ドメインの「@amail.com」を使うことにします)

from pyspark.sql.functions import col,concat
df_add_mail_address = (
    df_add_mail_domain
    .withColumn("mail_address",concat(col("name"),col("mail_domain"))
    )
)
df_add_mail_address.show()

【結果】
+---+-------+-----------+-----------------+
|age|   name|mail_domain|     mail_address|
+---+-------+-----------+-----------------+
|  2|  Alice| @amail.com|  Alice@amail.com|
| 50|    Bob| @amail.com|    Bob@amail.com|
| 12|Matilda| @amail.com|Matilda@amail.com|
+---+-------+-----------+-----------------+

ちなみに文法はこんな感じ。

(データフレーム).withColumn("新設するカラム名",concat(col("結合列①"),col("結合列②"))

いかがでしょうか?
この他にも「この列の値に特定の値を付与したいよね」というニーズには、上記のような「litで新列作る」→「concatで結合」の流れを踏むことで応えられる気がします。

あ、マチルダにメールは送らないでくださいね笑

このシリーズの目的

クラウドストレージに蓄積された生データ(CSV,JSON等)を加工するのに必要なPysparkの知識を溜めていく、まさに「Pysparkに関するトリビアのDalta Lake」を目指しています。
Pysparkに関する記事はまだ海外のものが多く、このシリーズが私のような国内の駆け出しデータエンジニアの一助になることを願っています。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?