我现在有很多键值对(键,值)
现在,对于一个密钥,我不想获得价值的平均值或其他一些汇总,我只需要一个值。 (获取不同的密钥)
我在这里举个例子,
("1","apple")
("1","apple")
("2","orange")
("2","orange")
("1","apple")
("1","pear")
结果可以是
("2","orange")
("1","apple")
或
("2","orange")
("1","pear")
我可以使用reduceByKey(((a,b) => a))
来获取此信息,但由于密钥很多,所以时间很长。
任何人都有更好的建议吗?
谢谢!
答案 0 :(得分:1)
Yiling,您可以使用转换 distinct 在RDD中保留不同的元素。 https://spark.apache.org/docs/1.3.1/api/scala/index.html#org.apache.spark.rdd.RDD
答案 1 :(得分:1)
实际上这是一个典型的map-reduce问题。但是你只需要每个键只有一个值,所以只需要你可以在减少阶段完成它,尽管它不是最好的方法。现在您知道使用reduceByKey只会花费大量时间进行无用的随机播放,这意味着您应该在Mapper中预先减少数据。所以答案显而易见:使用组合器。
在spark中,您可以在reduceByKey之前使用combineByKey来删除重复值。
==========
除了组合器,您还可以更改shuffle方法。 Spark 1.2+的默认shuffle是SortShuffle。您可以将其更改为HashShuffle,这可以降低分类键的成本。
尝试在sparkConf中设置它
spark.shuffle.manager = hash
spark.shuffle.consolidateFiles = true
但是你必须注意太多的地图核心可能会产生太多的混乱文件,这会影响性能。spark.shuffle.consolidateFiles
用于合并映射器输出文件。
答案 2 :(得分:1)
您可以使用dropDuplicates()
的DataFrame。
val df = sc.parallelize(
List(
("1", "apple"),
("1", "apple"),
("2", "orange"),
("2", "orange"),
("1", "apple"),
("1", "pear")
)
).toDF("count", "name")
df.show()
+-----+------+
|count| name|
+-----+------+
| 1| apple|
| 1| apple|
| 2|orange|
| 2|orange|
| 1| apple|
| 1| pear|
+-----+------+
按名称删除重复项
val uniqueDf = df.dropDuplicates("name")
现在选择前2个唯一行
uniqueDf.limit(2).show()
+-----+------+
|count| name|
+-----+------+
| 2|orange|
| 1| apple|
+-----+------+
无限制的唯一记录
uniqueDf.show()
+-----+------+
|count| name|
+-----+------+
| 2|orange|
| 1| apple|
| 1| pear|
+-----+------+
修改强>
您可以在DataFrame上使用collect()
将值输入List。