Java 正在尝试统计Spark中两个类别之间的唯一用户
我在Spark中有一个数据集结构,有两列,一列名为Java 正在尝试统计Spark中两个类别之间的唯一用户,java,sql,apache-spark,apache-spark-dataset,Java,Sql,Apache Spark,Apache Spark Dataset,我在Spark中有一个数据集结构,有两列,一列名为user,另一列名为category。这样表格看起来像这样: +---------------+---------------+ | user| category| +---------------+---------------+ | garrett| syncopy| | garrison| musictheory| | marta| sh
user
,另一列名为category
。这样表格看起来像这样:
+---------------+---------------+
| user| category|
+---------------+---------------+
| garrett| syncopy|
| garrison| musictheory|
| marta| sheetmusic|
| garrett| orchestration|
| harold| chopin|
| marta| russianmusic|
| niko| piano|
| james| sheetmusic|
| manny| violin|
| charles| gershwin|
| dawson| cello|
| bob| cello|
| george| cello|
| george| americanmusic|
| bob| personalcompos|
| george| sheetmusic|
| fred| sheetmusic|
| bob| sheetmusic|
| garrison| sheetmusic|
| george| musictheory|
+---------------+---------------+
only showing top 20 rows
+---------------+---------------+---------------+
| user| category| category|
+---------------+---------------+---------------+
| garrison| musictheory| sheetmusic|
| george| musictheory| sheetmusic|
| garrison| musictheory| musictheory|
| george| musictheory| musicthoery|
| garrison| sheetmusic| musictheory|
| george| sheetmusic| musictheory|
+---------------+---------------+---------------+
表中的每一行都是唯一的,但用户和类别可以出现多次。目标是统计两个类别共享的用户数。例如,cello
和americanmusic
共享名为george
和musictheory
和sheetmusic
的用户george
和garrison
。目标是获得n个类别之间不同用户的数量,这意味着类别之间最多有n个平方边。我部分了解如何进行此操作,但我正在努力将我的想法转换为Spark Java
我的想法是,我需要在user
上进行自联接,以获得如下结构的表:
+---------------+---------------+
| user| category|
+---------------+---------------+
| garrett| syncopy|
| garrison| musictheory|
| marta| sheetmusic|
| garrett| orchestration|
| harold| chopin|
| marta| russianmusic|
| niko| piano|
| james| sheetmusic|
| manny| violin|
| charles| gershwin|
| dawson| cello|
| bob| cello|
| george| cello|
| george| americanmusic|
| bob| personalcompos|
| george| sheetmusic|
| fred| sheetmusic|
| bob| sheetmusic|
| garrison| sheetmusic|
| george| musictheory|
+---------------+---------------+
only showing top 20 rows
+---------------+---------------+---------------+
| user| category| category|
+---------------+---------------+---------------+
| garrison| musictheory| sheetmusic|
| george| musictheory| sheetmusic|
| garrison| musictheory| musictheory|
| george| musictheory| musicthoery|
| garrison| sheetmusic| musictheory|
| george| sheetmusic| musictheory|
+---------------+---------------+---------------+
Spark(Java代码)中的自连接操作并不困难:
Dataset<Row> newDataset = allUsersToCategories.join(allUsersToCategories, "users");
Dataset newDataset=allUsersToCategories.join(allUsersToCategories,“用户”);
这是有意义的,但是我得到了与上面示例中的第3行和第4行相同的类别的映射,并且我得到了向后映射,其中类别是颠倒的,本质上是重复计算每个用户交互,就像上面示例中的第5行和第6行一样
我认为我需要做的是在我的连接中加入某种条件,它表示沿着X
的一些内容,这样就可以丢弃相同的类别和重复项。最后,我需要计算n个平方组合的不同行数,其中n是类别数
有人能解释一下如何在Spark中做到这一点吗?特别是Spark Java,因为我对Scala语法有点不熟悉
谢谢您的帮助。我不确定是否正确理解您的要求,但我会尽力帮助您 根据我的理解,上述数据的预期结果如下所示。如果这不是真的,请让我知道,我会尝试作出要求的修改
+--------------+--------------+-+
|_1 |_2 |
+--------------+--------------+-+
|personalcompos|sheetmusic |1|
|cello |musictheory |1|
|americanmusic |cello |1|
|cello |sheetmusic |2|
|cello |personalcompos|1|
|russianmusic |sheetmusic |1|
|americanmusic |sheetmusic |1|
|americanmusic |musictheory |1|
|musictheory |sheetmusic |2|
|orchestration |syncopy |1|
+--------------+--------------+-+
在这种情况下,您可以使用以下Scala代码解决问题:
allUsersToCategories
.groupByKey(_.user)
.flatMapGroups{case (user, userCategories) =>
val categories = userCategories.map(uc => uc.category).toSeq
for {
c1 <- categories
c2 <- categories
if c1 < c2
} yield (c1, c2)
}
.groupByKey(x => x)
.count()
.show()
我试图用Java提供示例,但我没有Java+Spark的任何经验,而且将上面的示例从Scala迁移到Java对我来说太耗时了。几小时前,我使用
Spark sql
找到了答案:
Dataset<Row> connection per shared user = spark.sql("SELECT a.user as user, "
+ "a.category as categoryOne, "
+ "b.category as categoryTwo "
+ "FROM allTable as a INNER JOIN allTable as b "
+ "ON a.user = b.user AND a.user < b.user");
Dataset connection per shared user=spark.sql(“选择一个.user作为用户,”
+“a.作为类别的类别,”
+“b.分类为类别2”
+“从allTable作为内部联接allTable作为b”
+“ON a.user=b.user和a.user
然后,这将创建一个包含三列的数据集
user
,categoryOne
,和categoryTwo
。每一行都是唯一的,并将指示用户何时存在于这两个类别中。编写SQL查询并执行它。任何过滤器都可以使用,SQL查询会显式使用什么