如何从一个列中删除所有子集,除了少数基于 Pyspark 中的其他列?
How to remove all the subset from a column except few based on the other column in Pyspark?
我有一个 pyspark 数据框,其中有一列列表(列 a
)和另一列数字(列 b
),我想保留所有超集行和子集在 b 列中的值大于它们的超集。
例如,
输入数据帧:
Column a = ([A,B,C],[A,C],[B,C],[J,S,K],[J,S],[J,K])
Column b = (10,15,7,8,9,8)
预期结果:
Column a = ([A,B,C],[A,C],[J,S,K],[J,S])
Column b = (10,15,8,9)
这里 [B,C]
和 [A,C]
是 [A,B,C]
的子集,但我们只保留 [A,C]
因为这个子集在 b
列中有 15
大于 10
列 b
中的超集 ([A,B,C]
) 值。
同样,超集 [J,S,K]
与其子集 [J,S]
一起保留,因为它在列 b
中的值大于超集列 b
的值。
您可以使用自 left_anti
连接来过滤满足该条件的行。
您的数据框中需要有一个 ID
列,这里我使用 monotonically_increasing_id
函数为每一行生成一个 ID
:
import pyspark.sql.functions as F
df = df.withColumn("ID", F.monotonically_increasing_id())
df.show()
#+---------+---+-----------+
#| a| b| ID|
#+---------+---+-----------+
#|[A, B, C]| 10| 8589934592|
#| [A, C]| 15|17179869184|
#| [B, C]| 7|25769803776|
#|[J, S, K]| 8|42949672960|
#| [J, S]| 9|51539607552|
#| [J, K]| 8|60129542144|
#+---------+---+-----------+
现在,要验证数组 arr1
是另一个数组 arr2
的子集,您可以使用 array_intersect
和 size
函数 size(array_intersect(arr1, arr2)) = size(arr1)
:
df_result = df.alias("df1").join(
df.alias("df2"),
(
(F.size(F.array_intersect("df1.a", "df2.a")) == F.size("df1.a"))
& (F.col("df1.b") <= F.col("df2.b"))
& (F.col("df1.ID") != F.col("df2.ID")) # not the same row
),
"left_anti"
).drop("ID")
df_result.show()
#+---------+---+
#| a| b|
#+---------+---+
#|[A, B, C]| 10|
#| [A, C]| 15|
#|[J, S, K]| 8|
#| [J, S]| 9|
#+---------+---+
我有一个 pyspark 数据框,其中有一列列表(列 a
)和另一列数字(列 b
),我想保留所有超集行和子集在 b 列中的值大于它们的超集。
例如,
输入数据帧:
Column a = ([A,B,C],[A,C],[B,C],[J,S,K],[J,S],[J,K])
Column b = (10,15,7,8,9,8)
预期结果:
Column a = ([A,B,C],[A,C],[J,S,K],[J,S])
Column b = (10,15,8,9)
这里 [B,C]
和 [A,C]
是 [A,B,C]
的子集,但我们只保留 [A,C]
因为这个子集在 b
列中有 15
大于 10
列 b
中的超集 ([A,B,C]
) 值。
同样,超集 [J,S,K]
与其子集 [J,S]
一起保留,因为它在列 b
中的值大于超集列 b
的值。
您可以使用自 left_anti
连接来过滤满足该条件的行。
您的数据框中需要有一个 ID
列,这里我使用 monotonically_increasing_id
函数为每一行生成一个 ID
:
import pyspark.sql.functions as F
df = df.withColumn("ID", F.monotonically_increasing_id())
df.show()
#+---------+---+-----------+
#| a| b| ID|
#+---------+---+-----------+
#|[A, B, C]| 10| 8589934592|
#| [A, C]| 15|17179869184|
#| [B, C]| 7|25769803776|
#|[J, S, K]| 8|42949672960|
#| [J, S]| 9|51539607552|
#| [J, K]| 8|60129542144|
#+---------+---+-----------+
现在,要验证数组 arr1
是另一个数组 arr2
的子集,您可以使用 array_intersect
和 size
函数 size(array_intersect(arr1, arr2)) = size(arr1)
:
df_result = df.alias("df1").join(
df.alias("df2"),
(
(F.size(F.array_intersect("df1.a", "df2.a")) == F.size("df1.a"))
& (F.col("df1.b") <= F.col("df2.b"))
& (F.col("df1.ID") != F.col("df2.ID")) # not the same row
),
"left_anti"
).drop("ID")
df_result.show()
#+---------+---+
#| a| b|
#+---------+---+
#|[A, B, C]| 10|
#| [A, C]| 15|
#|[J, S, K]| 8|
#| [J, S]| 9|
#+---------+---+