Pyspark中的反组by/R应用

Pyspark中的反组by/R应用,r,pyspark,group-by,sapply,pyspark-dataframes,R,Pyspark,Group By,Sapply,Pyspark Dataframes,我是一名进入pyspark世界的R程序员,已经掌握了很多基本技巧,但我仍在为我将要做的applys或basic for loops而挣扎 在本例中,我试图计算ID的反groupby。基本上,我们的想法是查看该ID的总体,然后查看非该ID的总体,并将这两个值放在同一行上。使用groupby获取该ID的填充很容易,然后将其连接到一个数据集,该数据集的唯一列是new_ID 这就是我在R中的做法: anti_group <- function(id){ tr <- sum(subse

我是一名进入pyspark世界的R程序员,已经掌握了很多基本技巧,但我仍在为我将要做的applys或basic for loops而挣扎

在本例中,我试图计算ID的反groupby。基本上,我们的想法是查看该ID的总体,然后查看非该ID的总体,并将这两个值放在同一行上。使用groupby获取该ID的填充很容易,然后将其连接到一个数据集,该数据集的唯一列是new_ID

这就是我在R中的做法:

anti_group <- function(id){
    tr <- sum(subset(df1, new_id!=id)$total_1)
    to <- sum(subset(df1, new_id!=id)$total_2)
    54 * tr / to
  }
  test$other.RP54 <- sapply(test$new_id, anti_group  )
然后是创建最终数据帧的函数,如下所示:

+---+-------------+------------------+
| id|grouped_total|anti_grouped_total|
+---+-------------+------------------+
|  1|           70|               137|
|  2|          100|               107|
|  3|           30|               177|
|  4|            7|               200|
+---+-------------+------------------+


因此,没有内置的函数可以复制groupBy函数,但是您可以通过使用casewhen/Others子句创建一个新列来轻松地实现这一点,以创建您的组和反组,然后在该新列上创建groupBy

更新:

实现相同输出的不太冗长/简洁的方法:

from pyspark.sql import functions as F
from pyspark.sql.window import Window
w = Window().partitionBy()
df.groupBy("id").agg(F.sum("value").alias("grouped_total"))\
          .withColumn("anti_grouped_total",F.sum("grouped_total").over(w)-F.col("grouped_total")).orderBy("id"),show()
对于2个值列:


因此,没有内置的函数可以复制groupBy函数,但是您可以通过使用casewhen/Others子句创建一个新列来轻松地实现这一点,以创建您的组和反组,然后在该新列上创建groupBy

更新:

实现相同输出的不太冗长/简洁的方法:

from pyspark.sql import functions as F
from pyspark.sql.window import Window
w = Window().partitionBy()
df.groupBy("id").agg(F.sum("value").alias("grouped_total"))\
          .withColumn("anti_grouped_total",F.sum("grouped_total").over(w)-F.col("grouped_total")).orderBy("id"),show()
对于2个值列:


我想你可以分两步来做:首先你用id求和,然后你取总数,然后用这个id的值减去

我的想法有点像dplyr中的一个组_byid%>%summarysex=sumx%>%mutatey=sumx-x

我提出的解决方案是基于窗口函数的。它未经测试:

让我们首先创建数据

将pyspark.sql.functions作为psf导入 将pyspark.sql.window作为psw导入 df=spark.createDataFrame[1,40,1,30,2,10,2,90,3,20,3,10,4,2,4,5],“id”和“value”] df.show2 +--+---+ |id |值| +--+---+ | 1| 40| | 1| 30| +--+---+ 仅显示前2行 然后应用这种方法:

w=psw.Window.orderBy df_id=df.groupByid.aggpsf.sumvalue.aliasgrouped_总计 df_id=df_id .带有列Anti_grouped_total,psf.sum grouped_total.over .带有“反分组总计”列,psf.列“反分组总计”-psf.列“分组总计” df_id.show2 +--+-------+---------+ |id |分组|总计|反分组|总计| +--+-------+---------+ | 3| 30| 177| | 1| 70| 137| +--+-------+---------+ 仅显示前2行
我想你可以分两步来做:首先你用id求和,然后你取总数,然后用这个id的值减去

我的想法有点像dplyr中的一个组_byid%>%summarysex=sumx%>%mutatey=sumx-x

我提出的解决方案是基于窗口函数的。它未经测试:

让我们首先创建数据

将pyspark.sql.functions作为psf导入 将pyspark.sql.window作为psw导入 df=spark.createDataFrame[1,40,1,30,2,10,2,90,3,20,3,10,4,2,4,5],“id”和“value”] df.show2 +--+---+ |id |值| +--+---+ | 1| 40| | 1| 30| +--+---+ 仅显示前2行 然后应用这种方法:

w=psw.Window.orderBy df_id=df.groupByid.aggpsf.sumvalue.aliasgrouped_总计 df_id=df_id .带有列Anti_grouped_total,psf.sum grouped_total.over .带有“反分组总计”列,psf.列“反分组总计”-psf.列“分组总计” df_id.show2 +--+-------+---------+ |id |分组|总计|反分组|总计| +--+-------+---------+ | 3| 30| 177| | 1| 70| 137| +--+-------+---------+ 仅显示前2行
我添加了一些更多的信息,以便更清楚。对不起!使用您的示例数据,感谢您的帮助。如果我们有4个ID,我可以手动迭代,但如果我有1000+个值,那么你的工作就不会很糟糕了。快速提问,如果我想创建两个分组列和两个反分组列,该怎么办?就像有一个值1和一个值2,并且想要分组值1、反分组值1、分组值2和反分组值2一样?u应该在groupby的agg中添加另一个和,然后添加另一个With列以使用窗口计算差异。查看我的更新中的2个值列。我添加了一些更清晰的信息。对不起!使用您的示例数据,感谢您的帮助。如果我们有4个ID,我可以手动迭代,但如果我有1000+个值,那么你的工作就不会很糟糕了。快速提问,如果我想创建两个分组列和两个反分组列,该怎么办?就像有一个值1和一个值2,并且想要分组值1、反分组值1、分组值2和反分组值2一样?u应该在groupby的agg中添加另一个和,然后添加另一个With列以使用窗口计算差异。查看我的更新中的2个值列。有趣的是,这绝对是一种方法。只需做一个group by,然后将完整的总体和附加到数据帧中,然后做简单的差分。我在编辑中添加了一些示例数据和示例输出,使其有点过时
我明白了。谢谢你的帮助!你们的答案基本相同,他基本上只是第一个。谢谢你的回复。@BaseballR你可以给他一个公认的答案,idc。我只是来帮助和学习的。干杯有趣的是,这绝对是一种方法。只需做一个group by,然后将完整的总体和附加到数据帧中,然后做简单的差分。我在编辑中添加了一些示例数据和示例输出,使其更加清晰。感谢您的帮助!你们的答案基本相同,他基本上只是第一个。谢谢你的回复。@BaseballR你可以给他一个公认的答案,idc。我只是来帮助和学习的。干杯
from pyspark.sql.window import Window
from pyspark.sql import functions as F

w1=Window().partitionBy("id")
w=Window().partitionBy()
df.withColumn("grouped_total",F.sum("value").over(w1))\
  .withColumn("anti_grouped_total", (F.sum("value").over(w))-F.col("grouped_total"))\
  .groupBy("id").agg(F.first("grouped_total").alias("grouped_total"),\
                     F.first("anti_grouped_total").alias("anti_grouped_total"))\
  .drop("value").orderBy("id").show()


+---+-------------+------------------+
| id|grouped_total|anti_grouped_total|
+---+-------------+------------------+
|  1|           70|               137|
|  2|          100|               107|
|  3|           30|               177|
|  4|            7|               200|
+---+-------------+------------------+
from pyspark.sql import functions as F
from pyspark.sql.window import Window
w = Window().partitionBy()
df.groupBy("id").agg(F.sum("value").alias("grouped_total"))\
          .withColumn("anti_grouped_total",F.sum("grouped_total").over(w)-F.col("grouped_total")).orderBy("id"),show()
df.show()
+---+------+------+
| id|value1|value2|
+---+------+------+
|  1|    40|    50|
|  1|    30|    70|
|  2|    10|    91|
|  2|    90|    21|
|  3|    20|    42|
|  3|    10|     4|
|  4|     2|    23|
|  4|     5|    12|
+---+------+------+

from pyspark.sql.window import Window
from pyspark.sql import functions as F

w = Window().partitionBy()
df.groupBy("id").agg(F.sum("value1").alias("grouped_total_1"),F.sum("value2").alias("grouped_total_2"))\
          .withColumn("anti_grouped_total_1",F.sum("grouped_total_1").over(w)-F.col("grouped_total_1"))\
          .withColumn("anti_grouped_total_2",F.sum("grouped_total_2").over(w)-F.col("grouped_total_2")).orderBy("id").show()

+---+---------------+---------------+--------------------+--------------------+
| id|grouped_total_1|grouped_total_2|anti_grouped_total_1|anti_grouped_total_2|
+---+---------------+---------------+--------------------+--------------------+
|  1|             70|            120|                 137|                 193|
|  2|            100|            112|                 107|                 201|
|  3|             30|             46|                 177|                 267|
|  4|              7|             35|                 200|                 278|
+---+---------------+---------------+--------------------+--------------------+