Apache spark Pyspark分组方式和条件计数数据

Apache spark Pyspark分组方式和条件计数数据,apache-spark,pyspark,apache-spark-sql,Apache Spark,Pyspark,Apache Spark Sql,我想用groupby函数解决一些问题。 让我给你看看我的箱子。 我的数据是这样的 | columnA | columnB | columnC | columnD | columnE | | ------- | ------- | ------- | ------- | ------- | | PersonA | DataOne | 20210101| 1 | 2 | | PersonA | DataOne | 20210102| 2 | 4 | |

我想用groupby函数解决一些问题。 让我给你看看我的箱子。 我的数据是这样的

| columnA | columnB | columnC | columnD | columnE |
| ------- | ------- | ------- | ------- | ------- |
| PersonA | DataOne | 20210101|    1    |    2    |
| PersonA | DataOne | 20210102|    2    |    4    |
| PersonA | DataOne | 20210102|    3    |    4    |
| PersonA | DataTwo | 20201226|    2    |    4    |
| PersonA | DataTwo | 20201226|    7    |    1    |
| PersonA | DataTwo | 20201227|    3    |    2    |
| PersonB | DataOne | 20201225|    1    |    3    |
| PersonB | DataTwo | 20201225|    2    |    4    |
| PersonB | DataTwo | 20201226|    1    |    2    |
然后,我要做的事情是按A、B、C列对D、E列进行聚合分组,但只使用 maxcolumnC

我用下面的代码完成了这项工作,但我一直想知道更简单更快的方法

my_df = (The data above)
my_df_max = my_df.groupBy("columnA","columnB").agg(max("columnC").alias("columnC"))
result = my_df\
    .groupBy("columnA","columnB","columnC")\
    .agg(count("columnD").alias("columnD"),sum("columnE").alias("columnE"))\
    .alias("tempA")\
    .join(my_df_max.alias("tempB"), (col("tempA.columnA") == col("tempB.columnA")) & (col("tempA.columnB") == col("tempB.columnB")) & (col("tempA.columnC") == col("tempB.columnC")))\
    .select(col("tempA.columnA"),col("tempA.columnB"), col("tempA.columnC"), col("columnD"), col("columnE"))
我预期的结果如下

|columnA|columnB|columnC |columnD|columnE|
|-------|-------|--------|-------|-------|
|PersonA|DataOne|20210102|   2   |   8   |
|PersonA|DataTwo|20201227|   1   |   2   |
|PersonB|DataOne|20201225|   1   |   3   |
|PersonB|DataTwo|20201226|   1   |   2   |

如果我碰巧知道实现这项工作的代码方式和SQL方式,我会非常高兴。

一个可能更简洁的选择是先按C列中的最大值筛选数据帧,然后进行聚合,假设您的spark数据帧名为sdf:


一个可能更简洁的选项是先按C列中的最大值过滤数据帧,然后进行聚合,假设spark数据帧的名称为sdf:


sparksql就是这样做的。您可以在适当的窗口上使用rank筛选具有max columnC的行,然后执行group by和聚合

df.createOrReplaceTempView('df')

result = spark.sql("""
    SELECT columnA, columnB, columnC, count(columnD) columnD, sum(columnE) columnE 
    FROM (
        SELECT *, rank() over(partition by columnA, columnB order by columnC desc) r 
        FROM df
    )
    WHERE r = 1
    GROUP BY columnA, columnB, columnC
""")

result.show()
+-------+-------+--------+-------+-------+
|columnA|columnB| columnC|columnD|columnE|
+-------+-------+--------+-------+-------+
|PersonB|DataOne|20201225|      1|      3|
|PersonA|DataOne|20210102|      2|      8|
|PersonB|DataTwo|20201226|      1|      2|
|PersonA|DataTwo|20201227|      1|      2|
+-------+-------+--------+-------+-------+

sparksql就是这样做的。您可以在适当的窗口上使用rank筛选具有max columnC的行,然后执行group by和聚合

df.createOrReplaceTempView('df')

result = spark.sql("""
    SELECT columnA, columnB, columnC, count(columnD) columnD, sum(columnE) columnE 
    FROM (
        SELECT *, rank() over(partition by columnA, columnB order by columnC desc) r 
        FROM df
    )
    WHERE r = 1
    GROUP BY columnA, columnB, columnC
""")

result.show()
+-------+-------+--------+-------+-------+
|columnA|columnB| columnC|columnD|columnE|
+-------+-------+--------+-------+-------+
|PersonB|DataOne|20201225|      1|      3|
|PersonA|DataOne|20210102|      2|      8|
|PersonB|DataTwo|20201226|      1|      2|
|PersonA|DataTwo|20201227|      1|      2|
+-------+-------+--------+-------+-------+