PySpark,一种分组方式,考虑顺序

时间:2018-08-07 11:18:08

标签: python pyspark apache-spark-sql

我有这种数据集:

+------+------+------+
| Time | Tool | Hole |
+------+------+------+
|    1 | A    | H1   |
|    2 | A    | H2   |
|    3 | B    | H3   |
|    4 | A    | H4   |
|    5 | A    | H5   |
|    6 | B    | H6   |
+------+------+------+

预期结果如下:这是我的数据的一种时间聚合,其中顺序很重要。

+------+-----------+---------+
| Tool | Time_From | Time_To |
+------+-----------+---------+
| A    |         1 |       2 |
| B    |         3 |       3 |
| A    |         4 |       5 |
| B    |         6 |       6 |
+------+-----------+---------+

使用groupby语句的当前结果与我的预期不符,因为未考虑顺序。

+------+-----------+---------+
| Tool | Time_From | Time_To |
+------+-----------+---------+
| A    |         1 |       5 |
| B    |         3 |       5 |
+------+-----------+---------+

rdd = rdd.groupby(['tool']).agg(min(rdd.time).alias('minTMSP'),
                                    max(rdd.time).alias('maxTMSP'))

我试图通过一个窗口函数,但到目前为止没有任何结果...知道如何在pyspark中处理此用例吗?

1 个答案:

答案 0 :(得分:1)

我们可以使用lag函数和Window类来检查每行中的条目是否相对于其前一行有所更改。然后,我们可以使用相同的Window计算累积总和,以找到要分组的列。从这一点出发,很容易找到每个组的最小和最大时间。

希望这会有所帮助!

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

df = spark.createDataFrame([(1,'A'), (2,'A'), (3,'B'),(4,'A'),(5,'A'),(6,'B')], 
                           schema=['Time','Tool'])

w = Window.partitionBy().orderBy('Time')

df2 = (df.withColumn('Tool_lag',F.lag(df['Tool']).over(w))
.withColumn('equal',F.when(F.col('Tool')==F.col('Tool_lag'), F.lit(0)).otherwise(F.lit(1)))
.withColumn('group', F.sum(F.col('equal')).over(w))
.groupBy('Tool','group').agg(
    F.min(F.col('Time')).alias('start'),
    F.max(F.col('Time')).alias('end'))
.drop('group'))
df2.show()

输出:

+----+-----+---+
|Tool|start|end|
+----+-----+---+
|   A|    1|  2|
|   B|    3|  3|
|   A|    4|  5|
|   B|    6|  6|
+----+-----+---+