对于输入Dataframe
,目的是仅生成自笛卡尔积的一半。鉴于笛卡尔积产生对称矩阵,我们只需要计算上方(或下方)设置为零的对角线上方或下方三角形部分:
数据框crossjoin
:
val df3 = df2.crossJoin(df2)
会生成 FULL - 这是我们不想要的。
鉴于相似性矩阵沿着对角线与1对称,我们不需要计算上半部分或对角线本身 - 如 LOWER DiagO'所示 在下面:
有关如何以最少的计算获得结果的任何建议?
答案 0 :(得分:0)
以下不是一个完美的答案:它确实导致首先生成完整的cartesian
产品。但至少输出结果是正确的。
/** Generate schema for cartesian product of an input dataframe */
def joinSchema(df: DataFrame) =
types.StructType(df.schema.fields.map {
f => StructField(s"${f.name}_a", f.dataType, f.nullable)
} ++ df.schema.fields.map { f => StructField(s"${f.name}_b", f.dataType, f.nullable)}
)
// Create the cartesian product via crossJoin
val schema = joinSchema(dfIn)
val df3 = df2.crossJoin(dfIn)
val cartesianDf = spark.createDataFrame(df3.rdd, schema)
cartDf.createOrReplaceTempView("cartesian")
// Retain the lower triangular entries below the diagonal
select * from cartesian where id_a < id_b