Java 使用GROUPBY根据两个不同的数据子集获取两个聚合的不同计数
假设我有这样的Java 使用GROUPBY根据两个不同的数据子集获取两个聚合的不同计数,java,apache-spark,apache-spark-sql,Java,Apache Spark,Apache Spark Sql,假设我有这样的Dataset Day User isInstall isPlayed 1 U1 1 1 1 U2 1 0 1 U3 0 1 1 U4 1 0 1 U4 1 1 2 U6 1 1 2 U7 1 0 2 U8 0
Dataset
Day User isInstall isPlayed
1 U1 1 1
1 U2 1 0
1 U3 0 1
1 U4 1 0
1 U4 1 1
2 U6 1 1
2 U7 1 0
2 U8 0 1
2 U8 0 1
2 U7 1 0
我想在Day字段上分组,并获得isInstall为1的唯一用户数&显示为1。结果应该是这样的:
Day isInstallUU isPlayedUU
1 3 3
2 2 2
我可以为iInstall获取不同的数据集&像这样显示计数,但我不知道如何合并它们并获取一个数据集
Dataset<Row> result1 = responseDataset.filter(col("isInstall").equalTo(1))
.groupBy("Day").agg(countDistinct("User").alias("isInstallUU"));
Dataset<Row> result2 = responseDataset.filter(col("isPlayed").equalTo(1))
.groupBy("Day").agg(countDistinct("User").alias("isPlayedUU"));
Dataset result1=responseDataset.filter(col(“isInstall”).equalTo(1))
.groupBy(“Day”).agg(countDistinct(“用户”).alias(“Isinstallu”);
数据集结果2=responseDataset.filter(列(“显示”).equalTo(1))
.groupBy(“日”).agg(countDistinct(“用户”).alias(“isPlayedUU”);
如何使用java Spark API实现这一点?首先,根据作者提供的条件过滤数据帧。然后使用GROUPBY按“天”列进行聚合,并附加两个新列,这两个列表示用户的不同计数。 检查以下代码:
responseDataset.filter(col("isInstall").equalTo(1) && col("isPlayed").equalTo(1))
.groupBy("Day")
.agg(countDistinct("User").as("isInstallUU"), countDistinct("User").as("isPlayedUU"));
首先,根据作者提供的条件过滤数据帧。然后使用GROUPBY按“天”列进行聚合,并附加两个新列,这两个列表示用户的不同计数。 检查以下代码:
responseDataset.filter(col("isInstall").equalTo(1) && col("isPlayed").equalTo(1))
.groupBy("Day")
.agg(countDistinct("User").as("isInstallUU"), countDistinct("User").as("isPlayedUU"));
一次完成这项工作有点棘手(但需要一些工作才能完成),因为您正在计算两个不同数据子集上的聚合 简单的解决方法是计算两个聚合(正如您尝试的那样)并将它们连接起来:
Dataset result1=responseDataset
.filter(col(“isInstall”).equalTo(1))
.groupBy(“日”)
.agg(countDistinct(“用户”)。别名(“ISINSTALLU”);
数据集结果2=响应数据集
.过滤器(列(“显示”).equalTo(1))
.groupBy(“日”)
.agg(countDistinct(“用户”)。别名(“isPlayedUU”);
数据集结果=结果1
.join(result2,result1.col(“日”)。equalTo(result1.col(“日”),“full_outer”)
.na().fill(0);
请注意,我使用完全外部联接,因为可能有用户未出现在这两个子集中。为了避免空值,我将它们替换为0
编辑:
如果你好奇,有一种方法可以在一个阶段完成。我们的想法是创建两个额外的用户列,当我们不想聚合它们时,这些用户列是空的(spark忽略countDistinct
中的空值)。它看起来是这样的:
数据集结果=响应数据集
.withColumn(“userI”,当(col(“isInstall”).equalTo(1),col(“user”))
.withColumn(“userP”,当(col(“isPlayed”)。等于(1),col(“user”))
.groupBy(“日”)
.agg(countDistinct(col(“userP”)).alias(“isPlayedUU”),
countDistinct(col(“userI”)。别名(“isinstallu”);
一次性完成这项工作有点棘手(但需要一些工作才能完成),因为您要计算两个不同数据子集的聚合 简单的解决方法是计算两个聚合(正如您尝试的那样)并将它们连接起来:
Dataset result1=responseDataset
.filter(col(“isInstall”).equalTo(1))
.groupBy(“日”)
.agg(countDistinct(“用户”)。别名(“ISINSTALLU”);
数据集结果2=响应数据集
.过滤器(列(“显示”).equalTo(1))
.groupBy(“日”)
.agg(countDistinct(“用户”)。别名(“isPlayedUU”);
数据集结果=结果1
.join(result2,result1.col(“日”)。equalTo(result1.col(“日”),“full_outer”)
.na().fill(0);
请注意,我使用完全外部联接,因为可能有用户未出现在这两个子集中。为了避免空值,我将它们替换为0
编辑:
如果你好奇,有一种方法可以在一个阶段完成。我们的想法是创建两个额外的用户列,当我们不想聚合它们时,这些用户列是空的(spark忽略countDistinct
中的空值)。它看起来是这样的:
数据集结果=响应数据集
.withColumn(“userI”,当(col(“isInstall”).equalTo(1),col(“user”))
.withColumn(“userP”,当(col(“isPlayed”)。等于(1),col(“user”))
.groupBy(“日”)
.agg(countDistinct(col(“userP”)).alias(“isPlayedUU”),
countDistinct(col(“userI”)。别名(“isinstallu”);
到目前为止,您尝试过什么吗?如果这能帮助您入门,那么在
函数
类中存在一个countDistinct
聚合函数:这可能很有用:@Oli我已经用我尝试过的方法编辑了我的帖子。您可以同时计算多个聚合.agg(sum(“col1”)、sum(“col2”)、…)
@Oli是的,我可以,但问题是我想在isInstall&isPlayed为1时统计不同的用户。请看一看我的例子,这可能会澄清这个问题。到目前为止,您尝试过什么吗?如果这能帮助您入门,那么在函数
类中存在一个countDistinct
聚合函数:这可能很有用:@Oli我已经用我尝试过的方法编辑了我的帖子。您可以同时计算多个聚合.agg(sum(“col1”)、sum(“col2”)、…)
@Oli是的,我可以,但问题是我想在isInstall&isPlayed为1时统计不同的用户。请看一看我的示例,这可能会澄清这个场景。首先,我根据作者提供的条件过滤数据帧。然后使用GROUPBY按“天”列进行聚合,并附加两个新列,这两个列表示用户的不同计数。不幸的是,这不起作用。您将错过所有已安装但未播放的用户以及已播放但未安装的用户。“或”对这一点也不起作用,因为我们对基于两个不同数据子集的两个聚合感兴趣。@himanshu srivastava说,他想在isInstall&isPlayed为1时计算不同的用户,首先根据作者提供的条件过滤数据帧。然后使用GROUPBY按“天”列进行聚合,并附加两个新列,这两个列表示用户的不同计数。不幸的是,这不起作用。您将错过所有已安装但未播放的用户以及已播放但未安装的用户。一个“或”字