基于条件的数据框聚合 (Pyspark)
Aggregation of a data frame based on condition (Pyspark)
我需要以下任务的帮助:
我获得了一个 groupby 结果,其中我有一个包含多个地址的列表(这里只是一个地址的剪切),其中有人占用了这些地址。我需要计算该应用程序的使用率,以便除以 [name] + Active Count / [name] + Passive Count 并使用 [address][name][usage_ratio]
我从来没有做过类似的聚合,我不知道从哪里开始或如何循环执行它。有人可以帮忙吗?
+------------+--------------------+----------------+-----+
| address| name| use_of_app|count|
+------------+--------------------+----------------+-----+
| 33| Mark| active| 35|
| 33| Mark| passive| 4|
| 33| Abbie| active| 30|
| 33| Abbie| passive| 2|
| 33| Anna| passive| 3|
| 33| Anna| active| 32|
| 33| Tom| passive| 38|
| 33| Tom| active| 50|
| 33| Patrick| passive| 40|
| 33| Patrick| active| 57|
+------------+--------------------+----------------+-----+
我找到了一个可行的解决方案,但它确实占用大量资源且耗时,因此我邀请大家使用 post 更快的工作解决方案。所以我的解决方案是采用上面的数据框,通过 .filter(use_of_app) 将其拆分为两个单独的 activeDF 和 passiveDF,然后根据 name = name 条件将它们重新组合在一起,并将 count(activeDF) 除以 count(activeDF)计数(被动DF)
这是我的代码 - 我在 count
列上使用 sum
,因为我不确定每个 use_of_app
有多少行:
from pyspark.sql import functions as F
df = df.groupBy("address", "name").agg(
(
F.sum(F.when(F.col("use_of_app") == "active", F.col("count")))
/ F.sum(F.when(F.col("use_of_app") == "passive", F.col("count")))
).alias("usage_ratio")
)
df.show()
+-------+-------+------------------+
|address| name| usage_ratio|
+-------+-------+------------------+
| 33| Abbie| 15.0|
| 33| Mark| 8.75|
| 33| Tom|1.3157894736842106|
| 33| Anna|10.666666666666666|
| 33|Patrick| 1.425|
+-------+-------+------------------+
另一种选择是 pivot
步:
from pyspark.sql import function as F
(
df.groupby("address", "name")
.pivot("use_of_app", values=["active", "passive"])
.agg(F.sum("count"))
.withColumn("ratio", F.col("active") / F.col("passive"))
.show()
)
# Output
+-------+-----+------+-------+------------------+
|address| name|active|passive| ratio|
+-------+-----+------+-------+------------------+
| 33|Abbie| 30| 2| 15.0|
| 33| Anna| 32| 3|10.666666666666666|
| 33| Mark| 35| 4| 8.75|
+-------+-----+------+-------+------------------+
+++
根据史蒂文的建议更新:.pivot("use_of_app", values=["active", "passive"])
.
我需要以下任务的帮助:
我获得了一个 groupby 结果,其中我有一个包含多个地址的列表(这里只是一个地址的剪切),其中有人占用了这些地址。我需要计算该应用程序的使用率,以便除以 [name] + Active Count / [name] + Passive Count 并使用 [address][name][usage_ratio]
我从来没有做过类似的聚合,我不知道从哪里开始或如何循环执行它。有人可以帮忙吗?
+------------+--------------------+----------------+-----+
| address| name| use_of_app|count|
+------------+--------------------+----------------+-----+
| 33| Mark| active| 35|
| 33| Mark| passive| 4|
| 33| Abbie| active| 30|
| 33| Abbie| passive| 2|
| 33| Anna| passive| 3|
| 33| Anna| active| 32|
| 33| Tom| passive| 38|
| 33| Tom| active| 50|
| 33| Patrick| passive| 40|
| 33| Patrick| active| 57|
+------------+--------------------+----------------+-----+
我找到了一个可行的解决方案,但它确实占用大量资源且耗时,因此我邀请大家使用 post 更快的工作解决方案。所以我的解决方案是采用上面的数据框,通过 .filter(use_of_app) 将其拆分为两个单独的 activeDF 和 passiveDF,然后根据 name = name 条件将它们重新组合在一起,并将 count(activeDF) 除以 count(activeDF)计数(被动DF)
这是我的代码 - 我在 count
列上使用 sum
,因为我不确定每个 use_of_app
有多少行:
from pyspark.sql import functions as F
df = df.groupBy("address", "name").agg(
(
F.sum(F.when(F.col("use_of_app") == "active", F.col("count")))
/ F.sum(F.when(F.col("use_of_app") == "passive", F.col("count")))
).alias("usage_ratio")
)
df.show()
+-------+-------+------------------+
|address| name| usage_ratio|
+-------+-------+------------------+
| 33| Abbie| 15.0|
| 33| Mark| 8.75|
| 33| Tom|1.3157894736842106|
| 33| Anna|10.666666666666666|
| 33|Patrick| 1.425|
+-------+-------+------------------+
另一种选择是 pivot
步:
from pyspark.sql import function as F
(
df.groupby("address", "name")
.pivot("use_of_app", values=["active", "passive"])
.agg(F.sum("count"))
.withColumn("ratio", F.col("active") / F.col("passive"))
.show()
)
# Output
+-------+-----+------+-------+------------------+
|address| name|active|passive| ratio|
+-------+-----+------+-------+------------------+
| 33|Abbie| 30| 2| 15.0|
| 33| Anna| 32| 3|10.666666666666666|
| 33| Mark| 35| 4| 8.75|
+-------+-----+------+-------+------------------+
+++
根据史蒂文的建议更新:.pivot("use_of_app", values=["active", "passive"])
.