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按“天”列进行聚合,并附加两个新列,这两个列表示用户的不同计数。不幸的是,这不起作用。您将错过所有已安装但未播放的用户以及已播放但未安装的用户。一个“或”字