2016-05-19 87 views
0

我的DataFrame df有一列充当与df多对一的表的外键。对于外键的每一个独特的价值,它含有其它外键,但只有一次,与遍布在该组中值是空的:PySpark DataFrame reduce_by

df.filter(df.foreignkey1 == "12345").select("foreignkey1", "foreignkey2").show() 

+-----------+-----------+ 
|foreignkey1|foreignkey2| 
+-----------+-----------+ 
|  12345|   | 
|  12345|   | 
|  12345|   | 
|  12345| 100002020| 
|  12345|   | 
+-----------+-----------+ 

在这里,我选择的所有条目,其中foreignkey1是12345,而在他们旁边显示foreignkey2的值。

我想倒塌下来到这一点:

+-----------+-----------+ 
|foreignkey1|foreignkey2| 
+-----------+-----------+ 
|  12345| 100002020| 
+-----------+-----------+ 

从理论上讲,应该只有一个foreignkey2foreignkey1独特的价值,尽管这部分正在测试。

我对Spark相当陌生,这似乎是一个问问别人的好地方,以确保我遵循“Spark思考”。任何帮助将非常感激。是我最好的选择df.rdd.reduceByKey还是有一些更智能的方式来使用groupby和聚合函数做到这一点?谢谢 !

+0

只是想:我很可能只是'dropna()',看看是否是长于唯一值的数量'foreignkey1'。但是,这并不能保证每个'foreignkey1'都有一个'foreignkey2' - 尽管它可能强烈地表明它。 – Quentin

回答

1

我认为这可能做的伎俩:

df.groupBy("fk").agg(max("fk2")) 

它将返回只有两列:fkmax(fk2)。第二列的每个值fkfk2的值最大。

但是,这种方法效率不高。因此,另外,如果你确信只有一个在fk2fk每个值值,你不需要等栏目,也许你可以做到以下几点:

df.select("fk", "fk2").filter(col("fk2").isNotNull()) 

否则,如果可以有更多不是每个fk一个fk2,你可以尝试合并这两种方法,作为一种尝试,以提高性能:

df.select("fk", "fk2").filter(col("fk2").isNotNull()).groupBy("fk").agg(max("fk2")) 
+0

第二种方法要好得多,如果Daniel的假设是正确的,从效率的角度来看 – David

+0

谢谢,一个很好的解决方案。在检查我的FK之间是否有一对一的映射关系时,第二个片段将会很有帮助:在运行它之后,我可以比较此DF中的行数与fk1的唯一值的数量。 – Quentin

相关问题