大家好,首先,根据标题有人可能会说问题已经回答,但我的观点是比较ReduceBykey,GroupBykey性能,特定于Dataset和RDD API。我在很多帖子中都看到,ReduceBykey方法的性能比GroupByKey更有效,当然我同意这一点。然而,我很困惑,如果我们使用数据集或RDD,我无法弄清楚这些方法的行为。每种情况应该使用哪一种?
我会尝试更具体,因此我将解决我的问题以及工作代码,我会尽快等待您的建议。
+---+------------------+-----+
|id |Text1 |Text2|
+---+------------------+-----+
|1 |one,two,three |one |
|2 |four,one,five |six |
|3 |seven,nine,one,two|eight|
|4 |two,three,five |five |
|5 |six,five,one |seven|
+---+------------------+-----+
这里的要点是检查第二个Colum的EACH行中是否包含第三个Colum,然后收集所有的thems ID。例如,第三列“one”的单词出现在第二列的句子中,ID为1,5,2,3。
+-----+------------+
|Text2|Set |
+-----+------------+
|seven|[3] |
|one |[1, 5, 2, 3]|
|six |[5] |
|five |[5, 2, 4] |
+-----+------------+
这是我的工作代码
List<Row> data = Arrays.asList(
RowFactory.create(1, "one,two,three", "one"),
RowFactory.create(2, "four,one,five", "six"),
RowFactory.create(3, "seven,nine,one,two", "eight"),
RowFactory.create(4, "two,three,five", "five"),
RowFactory.create(5, "six,five,one", "seven")
);
StructType schema = new StructType(new StructField[]{
new StructField("id", DataTypes.IntegerType, false, Metadata.empty()),
new StructField("Text1", DataTypes.StringType, false, Metadata.empty()),
new StructField("Text2", DataTypes.StringType, false, Metadata.empty())
});
Dataset<Row> df = spark.createDataFrame(data, schema);
df.show(false);
Dataset<Row> df1 = df.select("id", "Text1")
.crossJoin(df.select("Text2"))
.filter(col("Text1").contains(col("Text2")))
.orderBy(col("Text2"));
df1.show(false);
Dataset<Row> df2 = df1
.groupBy("Text2")
.agg(collect_set(col("id")).as("Set"));
df2.show(false);
我的问题详见3个子序列:
答案 0 :(得分:1)
TL; DR 两者都不好,但如果您使用Dataset
并使用Dataset
。
Dataset.groupBy
的行为与reduceByKey
相似。不幸的是,如果重复数量很少,collect_set
的行为与groupByKey
非常相似。使用reduceByKey
won't change a thing重写它。
如果你能提供一种在我的方法中存在更有效的替代解决方案
,我将不胜感激
您可以做的最好的事情是删除crossJoin
:
val df = Seq((1, "one,two,three", "one"),
(2, "four,one,five", "six"),
(3, "seven,nine,one,two", "eight"),
(4, "two,three,five", "five"),
(5, "six,five,one", "seven")).toDF("id", "text1", "text2")
df.select(col("id"), explode(split(col("Text1"), ",")).alias("w"))
.join(df.select(col("Text2").alias("w")), Seq("w"))
.groupBy("w")
.agg(collect_set(col("id")).as("Set")).show
+-----+------------+
| w| Set|
+-----+------------+
|seven| [3]|
| one|[1, 5, 2, 3]|
| six| [5]|
| five| [5, 2, 4]|
+-----+------------+