Я думаю, что вы можете сделать это в два этапа: сначала вы суммируете по идентификатору, затем берете сумму и вычитаете значение этого идентификатора.
Моя идея немного похожа на group_by(id) %>% summarise(x = sum(x)) %>% mutate(y = sum(x) - x)
в dplyr
Предлагаемое мной решение основано на функции Window
. Это не проверено:
Давайте сначала создадим данные
import pyspark.sql.functions as psf
import pyspark.sql.window as psw
df = spark.createDataFrame([(1,40),(1,30),(2,10),(2,90),(3,20),(3,10),(4,2),(4,5)], ['id','value'])
df.show(2)
+---+-----+
| id|value|
+---+-----+
| 1| 40|
| 1| 30|
+---+-----+
only showing top 2 rows
, а затем применим этот подход:
w = psw.Window.orderBy()
df_id = df.groupBy("id").agg(psf.sum("value").alias("grouped_total"))
df_id = (df_id
.withColumn("anti_grouped_total",psf.sum("grouped_total").over(w))
.withColumn('anti_grouped_total', psf.col('anti_grouped_total') - psf.col('grouped_total'))
)
df_id.show(2)
+---+-------------+------------------+
| id|grouped_total|anti_grouped_total|
+---+-------------+------------------+
| 3| 30| 177|
| 1| 70| 137|
+---+-------------+------------------+
only showing top 2 rows