是否可以将自定义类对象存储在Spark Data Frame中作为列值?

时间:2019-01-11 23:26:27

标签: dataframe pyspark lsh

我正在使用LSH算法解决重复文档检测问题。为了处理大规模数据,我们正在使用spark。

我大约有30万个文档,每个文档至少100-200个字。在Spark集群上,这些是我们在数据帧上执行的步骤。

  1. 运行Spark ML管道以将文本转换为令牌。

pipeline = Pipeline().setStages([
        docAssembler,
        tokenizer,
        normalizer,
        stemmer,
        finisher,
        stopwordsRemover,
       # emptyRowsRemover
    ])
model = pipeline.fit(spark_df)
final_df = model.transform(spark_df)

  1. 对于每个文档,使用datasketch(https://github.com/ekzhu/datasketch/)库获取MinHash值并将其存储为新列。
final_df_limit.rdd.map(lambda x: (CalculateMinHash(x),)).toDF()

第二步失败,因为火花不允许我们将自定义类型值存储为列。值是MinHash类的对象。

有人知道我如何在数据帧中存储Minhash对象吗?

1 个答案:

答案 0 :(得分:1)

我认为可能无法在DataFrames中保存python对象,但是您可以通过以下两种方式来规避这一点:

  • 存储结果而不是对象(不确定MinHash的工作方式,但是如果值是数字/字符串,则应该很容易从类对象中提取出来)。
  • 如果由于仍然需要对象的某些属性而不可行,则可能要使用Pickle对其进行序列化,将序列化的结果保存为编码字符串。这迫使您每次要使用该对象时都要取消序列化。

    final_df_limit.rdd.map(lambda x: base64.encodestring(pickle.dumps(CalculateMinHash(x),))).toDF()

  • 替代方法可能是改用Spark MinHash implementation,但这可能不适合您的所有要求。