PySpark:按两列分组,计算对,并除以两个不同列的平均值

时间:2021-03-09 03:37:44

标签: pyspark

我有一个包含多列的数据框,其中一些被标记为 PULocationID、DOLocationID、total_amount 和 trip_distance。我正在尝试按 PULocationID 和 DOLocationID 进行分组,然后将每个组合计数到名为“count”的列中。我还需要取 total_amount 和 trip_distance 的平均值,并将它们分成一个名为“trip_rate”的列。结束 DF 应该是:

<头>
PULocationID DOLocationID 计数 trip_rate
123 422 1 5.2435
3 27 4 6.6121

其中 (123,422) 配对一次,行程费用为 5.24 美元,(3, 27) 配对 4 次,行程费用为 6.61 美元。

通过阅读其他一些线程,我能够按位置分组并使用以下方法计算它们:

df.groupBy("PULocationID", 'DOLocationID').agg(count(lit(1)).alias("count")).show()

或者我可以按位置分组并使用以下方法获得我需要的两列的平均值:

df.groupBy("PULocationID", 'DOLocationID').agg({'total_amount':'avg', 'trip_distance':'avg'}).show()

我尝试了一些方法来获取trip_rate,但都没有奏效:

df.withColumn("trip_rate", (pyspark.sql.functions.col("total_amount") / pyspark.sql.functions.col("trip_distance"))) df.withColumn("trip_rate", df.total_amount/sum(df.trip_distance))

我也不知道如何组合两个有效的查询(即位置计数 + 平均值)。

1 个答案:

答案 0 :(得分:1)

以此作为输入数据帧的示例:

+------------+------------+------------+-------------+
|PULocationID|DOLocationID|total_amount|trip_distance|
+------------+------------+------------+-------------+
|         123|         422|      10.487|            2|
|           3|          27|     19.8363|            3|
|           3|          27|     13.2242|            2|
|           3|          27|      6.6121|            1|
|           3|          27|     26.4484|            4|
+------------+------------+------------+-------------+

您可以将 groupByaggselect 链接在一起(如果您只需要 4 列,也可以使用 withColumndrop) .

import pyspark.sql.functions as F

new_df = df.groupBy(
    "PULocationID",
    "DOLocationID",
).agg(
    F.count(F.lit(1)).alias("count"),
    F.avg(F.col("total_amount")).alias("avg_amt"),
    F.avg(F.col("trip_distance")).alias("avg_distance"),
).select(
    "PULocationID",
    "DOLocationID",
    "count",
    (F.col("avg_amt") / F.col("avg_distance")).alias("trip_rate")
)

new_df.show()
+------------+------------+-----+-----------------+
|PULocationID|DOLocationID|count|        trip_rate|
+------------+------------+-----+-----------------+
|         123|         422|    1|           5.2435|
|           3|          27|    4|6.612100000000001|
+------------+------------+-----+-----------------+