簡體   English   中英

pyspark SparseVectors dataframe columns.dot product 或使用@udf 或@pandas_udf 的任何其他向量類型的列計算

[英]pyspark SparseVectors dataframe columns .dot product or any other vectors type column computation using @udf or @pandas_udf

我確實嘗試計算給定 dataframe 的 2 列之間的.dot積, SparseVectors已經在 spark 中具有這種能力所以我嘗試以一種簡單且可擴展的方式執行它而不轉換為RDDDenseVectors但我被卡住了,過去了3 天嘗試找出一種方法,但確實失敗了,不返回從 dataframe 傳遞的 2 個向量列的計算,請尋求有關此事的指導,因為我在這里遺漏了一些東西並且不確定根本原因是什么。 ..

對於單獨的向量和 rdd 向量,這種方法有效,但在傳遞 dataframe 列向量時無法正常工作,要復制流程和問題,請參見下文,理想情況下,這種計算是並行發生的,因為實際工作數據有數十億或更多行(數據框觀察):

from pyspark.ml.linalg import Vectors, SparseVector
    from pyspark.sql import Row
    df = spark.createDataFrame(
        [
         [["a","b","c"], SparseVector(4527, {0:0.6363067860791387, 1:1.0888040725098247, 31:4.371858972705023}),SparseVector(4527, {0:0.6363067860791387, 1:2.0888040725098247, 31:4.371858972705023})],
         [["d"], SparseVector(4527, {8: 2.729945780576634}), SparseVector(4527, {8: 4.729945780576634})],
        ], ["word", "i", "j"])

# # daframe content
df.show()
+---------+--------------------+--------------------+
|     word|                   i|                   j|
+---------+--------------------+--------------------+
|[a, b, c]|(4527,[0,1,31],[0...|(4527,[0,1,31],[0...|
|      [d]|(4527,[8],[2.7299...|(4527,[8],[4.7299...|
+---------+--------------------+--------------------+


@udf(returnType=ArrayType(FloatType()))
def sim_cos(v1, v2):
    if v1 is not None and v2 is not None:
        return float(v1.dot(v2))

# # calling udf
df = df.withColumn("dotP", sim_cos(df.i, df.j))

# # output after udf 
df.show()
+---------+--------------------+--------------------+----------+
|     word|                   i|                   j|      dotP|
+---------+--------------------+--------------------+----------+
|[a, b, c]|(4527,[0,1,31],[0...|(4527,[0,1,31],[0...|      null|
|      [d]|(4527,[8],[2.7299...|(4527,[8],[4.7299...|      null|
+---------+--------------------+--------------------+----------+

將 udf 重寫為 lambda 確實適用於 spark 2.4.5。 如果有人對 PySpark 數據幀的這種方法感興趣,請發帖:

# # rewrite udf as lambda function:
sim_cos = F.udf(lambda x,y : float(x.dot(y)), FloatType())

# # executing udf on dataframe
df = df.withColumn("similarity", sim_cos(col("i"),col("j")))

# # end result
df.show()

+---------+--------------------+--------------------+----------+
|     word|                   i|                   j|similarity|
+---------+--------------------+--------------------+----------+
|[a, b, c]|(4527,[0,1,31],[0...|(4527,[0,1,31],[0...| 21.792336|
|      [d]|(4527,[8],[2.7299...|(4527,[8],[4.7299...| 12.912496|
+---------+--------------------+--------------------+----------+

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM