私は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"]))
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ビルトインとは異なるハッシュアルゴリズムを使用しているようです。