首页 > 解决方案 > 考虑到可能的列排列,删除 spark 数据帧重复项

问题描述

您好,我有一个具有以下结构的数据框

df = sqlContext.createDataFrame([
("x1","y1","z","w1"),
("y1","x1","w1","z"),
("y3","x1","w3","z"),
("y4","x2","w4","q"),
("x2","y5","q","p1"),
("x2","y4","q","w4"),
], ["test1_1", "test2_1","test1_2","test2_2"])

+-------+-------+-------+-------+
|test1_1|test2_1|test1_2|test2_2|
+-------+-------+-------+-------+
|x1     |y1     |z      |w1     |
|y1     |x1     |w1     |z      |
|y3     |x1     |w3     |z      |
|y4     |x2     |w4     |q      |
|x2     |y5     |q      |p1     |
|x2     |y4     |q      |w4     |
+-------+-------+-------+-------+  

现在我想根据列 test1_2、test2_2 的可能排列删除重复项,并保持 test1_1-test1_2 和 test2_1-test2_2 之间的顺序关系,并在同一列上具有相同的值。

目标输出:

+-------+-------+-------+-------+
|test1_1|test2_1|test1_2|test2_2|
+-------+-------+-------+-------+
|x1     |y1     |z      |w1     |
|x1     |y3     |z      |w3     |
|x2     |y4     |q      |w4      
|x2     |y5     |q      |p1     |
+-------+-------+-------+-------+  

到目前为止,这就是我所做的:
首先我连接了 test1_1-test1_2 和 test2_1-test2_2 以保留顺序:

df=df.withColumn('test1_2_1_1',F.concat_ws(';',F.col('test1_2'),F.col('test1_1')))
df=df.withColumn('test2_2_2_1',F.concat_ws(';',F.col('test2_2'),F.col('test2_1')))

然后我重新排列了列以删除重复项:

df= df.select(F.least(df.test1_2_1_1,df.test2_2_2_1).alias('test1_2_1_1'),F.greatest(df.test1_2_1_1,df.test2_2_2_1).alias('test2_2_2_1'))
df=df.dropDuplicates(subset=['test1_2_1_1','test2_2_2_1'])

我现在可以再次拆分字符串:

df=df.withColumn("test1_2", F.split(F.col("test1_2_1_1"), ";").getItem(0)).withColumn("test1_1", F.split(F.col("test1_2_1_1"), "-").getItem(1))
df=df.withColumn("test2_2", F.split(F.col("test2_2_2_1"), ";").getItem(0)).withColumn("test2_1", F.split(F.col("test2_2_2_1"), "-").getItem(1))

虽然这会正确删除重复项,但它会根据字符串的最大/最小标准更改列的顺序,因此在此阶段我有以下数据框,这不是所需的输出:

+-------+-------+-------+-------+
|test1_1|test2_1|test1_2|test2_2|
+-------+-------+-------+-------+
|y1     |x1     |w1     |z      |
|y3     |x1     |w3     |z      |
|x2     |y4     |q      |w4     | 
|y5     |x2     |p1     |q      |
+-------+-------+-------+-------+  
  1. 到目前为止有没有更好的方法来删除这些重复项?
  2. 我如何重新排序 test1_2 和 test2_2 列中的值以在同一列中具有相同的值(不管哪一列),同时保持与 test1_1 和 test2_1 的正确配对?有关实际示例,请参见上面的输出数据框

标签: pythondataframeapache-sparkpyspark

解决方案


推荐阅读