web-dev-qa-db-ja.com

PySpark-列としてマップ関数を追加する

私はpyspark DataFrameを持っています

a = [
    ('Bob', 562),
    ('Bob',880),
    ('Bob',380),
    ('Sue',85),
    ('Sue',963)
] 
df = spark.createDataFrame(a, ["Person", "Amount"])

Amountをハッシュして量を返す列を作成する必要があります。問題は、UDFを使用できないため、マッピング関数を使用したことです。

df.rdd.map(lambda x: hash(x["Amount"]))
5
Bryce Ramgovind

udfを使用できない場合は、map関数を使用できますが、現在作成しているため、列は1つしかありません。すべての列を保持するには、次のようにします。

_df = df.rdd\
    .map(lambda x: (x["Person"], x["Amount"], hash(str(x["Amount"]))))\
    .toDF(["Person", "Amount", "Hash"])

df.show()
#+------+------+--------------------+
#|Person|Amount|                Hash|
#+------+------+--------------------+
#|   Bob|   562|-4340709941618811062|
#|   Bob|   880|-7718876479167384701|
#|   Bob|   380|-2088598916611095344|
#|   Sue|    85|    7168043064064671|
#|   Sue|   963|-8844931991662242457|
#+------+------+--------------------+
_

:この場合、hash(x["Amount"])はあまり面白くないので、ハッシュAmountに変換して、ストリング。

基本的に、既存のすべての列を含むタプルに行をマップし、新しい列に追加する必要があります。

列が多すぎて列挙できない場合は、既存の行にタプルを追加することもできます。

_df = df.rdd\
    .map(lambda x: x + (hash(str(x["Amount"])),))\
    .toDF(df.columns + ["Hash"])\
_

また、値をハッシュすることが最終目標である場合は、pyspark関数 _pyspark.sql.functions.hash_ を使用してrddへのシリアル化を回避できることも指摘しておきます。

_import pyspark.sql.functions as f
df.withColumn("Hash", f.hash("Amount")).show()
#+------+------+----------+
#|Person|Amount|      Hash|
#+------+------+----------+
#|   Bob|   562|  51343841|
#|   Bob|   880|1241753636|
#|   Bob|   380| 514174926|
#|   Sue|    85|1944150283|
#|   Sue|   963|1665082423|
#+------+------+----------+
_

pythonビルトインとは異なるハッシュアルゴリズムを使用しているようです。

14
pault