Spark获取列中数组中具有相同值的所有行

费德里科·塔钦(Federico Taschin)

我有一个带有列id的Spark Dataframe hashes,其中列hashes包含一个Seqlength的整数值n例:

+----+--------------------+
+  id|              hashes|
+----+--------------------+
|0   |     [1, 2, 3, 4, 5]|
|1   |     [1, 5, 3, 7, 9]|
|2   |     [9, 3, 6, 8, 0]|
+-------------------------+

我想获得一个数据帧,其中所有与之hashes匹配的行至少在一个位置匹配。更正式地说,我想和一个额外的列数据帧matches,对于每一行r包含Seqid行S其中hashes[r][i] == hashes[k][i]k是任何其他行在执法机关的一个值i

对于我的示例数据,结果将是:

+---+---------------+-------+
|id |hashes         |matches|
+---+---------------+-------+
|0  |[1, 2, 3, 4, 5]|[1]    |
|1  |[1, 5, 3, 7, 9]|[0]    |
|2  |[9, 3, 6, 8, 0]|[]     |
+---+---------------+-------+
文森特·多巴(Vincent Doba)

在Spark 3中,以下代码在行之间比较数组,仅保留两个数组在同一位置共享至少一个元素的行。df是您的输入数据框:

    df.join(
      df.withColumnRenamed("id", "id2").withColumnRenamed("hashes", "hashes2"),
      exists(arrays_zip(col("hashes"), col("hashes2")), x => x("hashes") === x("hashes2"))
    )
      .groupBy("id")
      .agg(first(col("hashes")).as("hashes"), collect_list("id2").as("matched"))
      .withColumn("matched", filter(col("matched"), x => x.notEqual(col("id"))))

详细说明

首先,我们执行自动交叉联接,并根据您在两个哈希数组上相同位置的至少一个元素的条件进行过滤。

为了建立条件,我们压缩两个哈希数组,一个哈希数组来自第一个数据帧,一个哈希数组用于第二个连接的数据帧,也就是第一个已重命名列的数据帧。通过压缩,我们得到的数组,{"hashes":x, "hashes2":y}接下来我们只需检查该数组中是否存在where元素x = y完整的条件如下:

exists(arrays_zip(col("hashes"), col("hashes2")), x => x("hashes") === x("hashes2"))

然后,我们将按列汇总id以收集所有id2保留的行,这意味着符合您条件的行

为了保持“哈希”列,对于具有相同“ id”的两行,“哈希”列相等,我们为每个“ id”获得“哈希”的第一个匹配项。然后,我们使用collect_list收集所有“ id2”

.agg(first(col("hashes")).as("hashes"), collect_list("id2").as("matches"))

最后,我们从“匹配”列中过滤出当前行的ID

.withColumn("matches", filter(col("matches"), x => x.notEqual(col("id"))))

如果需要按顺序排列“ id”,则可以添加一个orderBy子句:

.orderBy("id")

对于df包含以下值的数据框

+---+---------------+
|id |hashes         |
+---+---------------+
|0  |[1, 2, 3, 4, 5]|
|1  |[1, 5, 3, 7, 9]|
|2  |[9, 3, 6, 8, 0]|
+---+---------------+

您将获得以下输出:

+---+---------------+-------+
|id |hashes         |matches|
+---+---------------+-------+
|0  |[1, 2, 3, 4, 5]|[1]    |
|1  |[1, 5, 3, 7, 9]|[0]    |
|2  |[9, 3, 6, 8, 0]|[]     |
+---+---------------+-------+

限度

联接是笛卡尔积,非常昂贵。尽管条件过滤器会过滤结果,但它可能导致大型数据集上的大量计算/混洗,并且性能可能非常差。

如果使用版本低于3.0的Spark,则必须用户定义的函数替换一些内置的spark函数

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何通过熊猫或spark数据框删除所有行中具有相同值的列?

删除所有列中具有相同值的行

删除熊猫所有列中具有相同值的重复行

删除所有列中具有相同值的行

如果另一列在SQL Server中相同,则获取具有最小列值的行

查询以获取3列中具有相同值且1之中具有不同值的行

获取所有在python中具有相同值的行?

我想获取具有相同字段名称的对象中的所有值并存储在数组中

获取所有在熊猫中具有相同值的行

从数据库中获取在laravel中具有特定列值的所有行

获取在pandas的各列中具有相同值的行

将某列中具有相同值的excel中的所有行求和

如何从MySQL表中获取具有多列相同值的所有行?

在MYSQL中,仅获取具有相同值的那些列

如何提取与某行相同的一列中具有相同值的所有行?

获取两列中具有相同值的行数据

对于每一行,查找列中具有相同值的所有行

如何从除 MSSQL 中的一列之外的所有列中具有相同数据的 2 行获取数据

选择不同列中具有相同值的行或 null 。有多行具有相同的 id

如果 hashMap 具有相同的键名,我如何获取对象数组中的所有值

如何保留数据框中所有列中具有相同值的所有行?

获取在 laravel 5.7 的列中具有指定值之一的所有行

在 SQL 中获取列 A 中具有相同值的所有行,这些行在列 B 中只有非空值

使用awk获取在一列中具有相同值的各行的所有值

过滤掉所有行中具有相同值的列

如何在 Pandas 中其他指定行的特定列集上获取所有具有相同值的行?

Pyspark:如何为另一列中具有相同值的所有行设置相同的 id?

計算所有列中具有相同值的行

根据pyspark中另一列的值编辑具有相同id的列的所有行的值