我现在有很多键值对(键,值)
现在,对于一个键,我不想获得该值的平均值或其他某些聚合,我只需要一个值。(获取独特的键)
让我在这里有一个例子,
("1","apple")
("1","apple")
("2","orange")
("2","orange")
("1","apple")
("1","pear")
结果可以是
("2","orange")
("1","apple")
或
("2","orange")
("1","pear")
我可以使用reduceByKey(((a,b) => a))
来获取此功能,但是由于有很多键,时间很长。
有人有一些更好的建议?
谢谢!
实际上它是典型的地图 - 诸如问题。但是您只需要每个键的值一个值,因此,您可以在减少阶段进行操作,尽管这不是最好的方法。现在,您知道,使用driedbykey只会花费大量时间在无用的洗牌中花费大量时间,这意味着您应该在映射器中预先删除数据。因此,答案对您来说是显而易见的:使用Combiner。
在Spark中,您可以在ReedbyKey之前使用CombineByKey来删除重复值。
===========
除了组合仪外,您还可以更改洗牌方法。Spark 1.2 的默认散装是分类的。您可以将其更改为可以降低排序键的成本的悬浮纸条。
尝试将其设置在您的SparkConf
spark.shuffle.manager = hash
spark.shuffle.consolidateFiles = true
,但是您必须注意,地图核心过多可能会产生过多的洗牌文件,从而影响性能。spark.shuffle.consolidateFiles
用于合并映射器输出文件。
yiling,您可以使用转换不同的在RDD中保留不同的元素。https://spark.apache.org/docs/1.3.1/api/scala/index.html#org.apache.spark.rdd.rdd.rdd.rdd
您可以使用DataFrame的dropDuplicates()
。
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()
将值输入列表。