cas*_*sen 2 python apache-spark apache-spark-sql pyspark
我们有一个包含大量文件的数据湖,我可以在其中读取这些文件的内容及其路径:
sdf = spark.read.load(source)\
.withColumn("_path", F.input_file_name())
Run Code Online (Sandbox Code Playgroud)
我想为每一行生成一个唯一的 ID,以便更轻松地在表之间进行下游连接,并且我希望该 ID 在运行之间可重现。
最简单的方法是简单地使用_path列作为标识符。
sdf = spark.read.load(source)\
.withColumn("_path", F.input_file_name())
Run Code Online (Sandbox Code Playgroud)
然而,拥有某种整数表示形式会“更漂亮”且更紧凑。对于其他表,唯一标识符可能是几列的组合,这会让情况变得更加丑陋。
另一种方法是使用单调递增的 ID。
sdf.withColumn("id", F.monotonically_increasing_id())
Run Code Online (Sandbox Code Playgroud)
但是,在此解决方案中,不能保证运行分析时 id=2 也在一周后(新数据到达时)运行分析时 id=2。
第三种方法是使用哈希函数:
sdf.withColumn("id", F.col("_path"))
Run Code Online (Sandbox Code Playgroud)
这可能非常好,因为很容易对列的组合进行散列,但这并不稳定,因为多个输入可以给出相同的输出:
对我们的实际数据进行此类分析,得出来自单个来源的 396,702 个哈希 ID _path,以及来自两个路径的 24 个哈希 ID。因此碰撞率为 0.006%。
我们可以简单地忽略这极小部分的数据,但一定有一种更优雅的方式来实现我想要实现的目标?
您可以尝试xxhash64Spark SQL 中的哈希,它提供 64 位哈希值,并且对于哈希冲突应该更稳健:
sdf.withColumn("id", F.expr("xxhash64(_path)"))
Run Code Online (Sandbox Code Playgroud)
或者使用更强大的哈希算法,
sdf.withColumn("id", F.expr("conv(sha2(_path,256),16,10)"))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2156 次 |
| 最近记录: |