You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySpark中将逗号分隔字符串列转换为稠密向量的方法

解决方案

问题背景

现有两个结构一致的PySpark DataFrame,需执行cross join后计算余弦相似度,其中qry_emb为字符串类型列,存储逗号分隔的嵌入向量数值,DataFrame表结构如下:

df.printSchema()
# root
# |-- query: string (nullable = true)
# |-- qry_emb: string (nullable = true)

DataFrame示例参考:
Pyspark dataframe示例

字符串转Dense Vector实现

可选择以下任意一种方式完成转换:

  • 内置函数转换(推荐,无UDF序列化开销,性能更好,适配Spark 3.0+版本)
from pyspark.sql import functions as F

# 对第一个DataFrame做转换
df1 = df1.withColumn(
    "qry_emb_vec",
    # 先按逗号拆分字符串为数组,转浮点类型后调用内置函数转为Dense Vector
    F.array_to_vector(F.split(F.col("qry_emb"), ",").cast("array<float>"))
)

# 提前重命名第二个DataFrame的同名列,避免cross join后字段冲突
df2 = df2.withColumnRenamed("query", "doc_query").withColumnRenamed("qry_emb", "doc_emb")
df2 = df2.withColumn(
    "doc_emb_vec",
    F.array_to_vector(F.split(F.col("doc_emb"), ",").cast("array<float>"))
)
  • UDF转换(逻辑直观,兼容所有Spark版本)
from pyspark.sql import functions as F
from pyspark.ml.linalg import DenseVector, VectorUDT

# 定义转换UDF
@F.udf(returnType=VectorUDT())
def str_to_densevec(emb_str):
    if not emb_str:
        return None
    return DenseVector([float(val.strip()) for val in emb_str.split(",")])

# 分别对两个DataFrame执行转换
df1 = df1.withColumn("qry_emb_vec", str_to_densevec("qry_emb"))
df2 = df2.withColumnRenamed("query", "doc_query").withColumnRenamed("qry_emb", "doc_emb")
df2 = df2.withColumn("doc_emb_vec", str_to_densevec("doc_emb"))

Cross Join与余弦相似度计算

完成向量转换后即可执行关联和相似度计算:

# 执行笛卡尔关联
cross_res = df1.crossJoin(df2)

# Spark 3.2+可直接用内置余弦相似度函数计算
final_res = cross_res.withColumn(
    "cosine_similarity",
    F.cosine_similarity(F.col("qry_emb_vec"), F.col("doc_emb_vec"))
)

如果使用低于3.2的Spark版本,可通过UDF实现相似度计算:

from pyspark.sql.types import FloatType
import numpy as np

@F.udf(returnType=FloatType())
def cos_sim(v1, v2):
    return float(np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2)))

final_res = cross_res.withColumn("cosine_similarity", cos_sim("qry_emb_vec", "doc_emb_vec"))

注意:Cross join会生成笛卡尔积,当两个DataFrame数据量较大时会出现数据量爆炸,极易耗尽集群计算资源,大数据量场景建议使用LSH算法做近似近邻匹配替代全量cross join计算。

内容的提问来源于stack exchange,提问作者Sree Aurovindh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 22:48:22