【问题标题】:Vector operation on Pyspark dataframe: angles between two vectorsPyspark 数据帧上的向量操作:两个向量之间的角度
【发布时间】:2022-01-16 14:58:53
【问题描述】:
df = spark.createDataFrame([[10, 8, 7, 6], [3, 5, 9 ,2], [1, 3, 4, 7], [1, 5, 9, 3], [2, 8, 2, 0], [8, 7, 3, 6]], list('ABCD'))
df.show()
+---+---+---+---+
|  A|  B|  C|  D|
+---+---+---+---+
| 10|  8|  7|  6|
|  3|  5|  9|  2|
|  1|  3|  4|  7|
|  1|  5|  9|  3|
|  2|  8|  2|  0|
|  8|  7|  3|  6|
+---+---+---+---+

通过VectorAssembler将cols转换成向量:

from pyspark.ml.feature import VectorAssembler
Vector = VectorAssembler(inputCols=['A','B'], outputCol="Vector_AB").transform(df)
Vector = VectorAssembler(inputCols=['C','D'], outputCol="Vector_CD").transform(Vector)
Vector.show()

    +---+---+---+---+----------+---------+
    |  A|  B|  C|  D| Vector_AB|Vector_CD|
    +---+---+---+---+----------+---------+
    | 10|  8|  7|  6|[10.0,8.0]|[7.0,6.0]|
    |  3|  5|  9|  2| [3.0,5.0]|[9.0,2.0]|
    |  1|  3|  4|  7| [1.0,3.0]|[4.0,7.0]|
    |  1|  5|  9|  3| [1.0,5.0]|[9.0,3.0]|
    |  2|  8|  2|  0| [2.0,8.0]|[2.0,0.0]|
    |  8|  7|  3|  6| [8.0,7.0]|[3.0,6.0]|
    +---+---+---+---+----------+---------+

如何计算Vector_ABVector_CD之间的夹角?

有没有可以做这个计算的内置函数?

我尝试:

from pyspark.ml.linalg import Vectors
angle_udf = F.udf(lambda x,y : x.dot(y) / (Vectors.norm(x,p=2) * Vectors.norm(y,p=2)),FloatType())
Vector = Vector.withColumn("Angle", angle_udf("Vector_AB","Vector_CD")).show()

【问题讨论】:

    标签: vector pyspark


    【解决方案1】:

    您可以使用acosdotnorm 函数来计算向量之间的角度。

    我们将使用的公式是

    angle = f.acos(x.dot(y) / (norm(x) * norm(y))
    

    PySpark 向量(用于点和范数):https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.ml.linalg.Vectors.html

    Cos 反函数: https://spark.apache.org/docs/3.1.1/api/python/reference/api/pyspark.sql.functions.acos.html

    【讨论】:

    • 我尝试:from pyspark.ml.linalg import Vectorsangle_udf = F.udf(lambda x,y : F.acos(x.dot(y) / (Vectors.norm(x,p=2) * Vectors.norm(y,p=2))),VectorUDT())Vector = Vector.withColumn("Angle",angle_udf("Vector_AB","Vector_CD")) 然后我收到错误:` PythonException:从 UDF 引发异常:'TypeError:无效参数,不是字符串或列: 0.4474575643275654 类型。对于列文字,请使用“lit”、“array”、“struct”或“create_map”函数。',来自,第 2 行。`
    • 不要使用 udf,它会极大地影响性能。仅使用 spark API
    • 如何按列计算? Vector.withColumn("Angle", F.acos(Vector['Vector_AB'].dot(Vector['Vector_CD']) / (norm(Vector['Vector_AB']) * norm(Vector['Vector_CD']))))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-20
    • 1970-01-01
    相关资源
    最近更新 更多