我想计算每个用户在每个SeqID上花费的时间。我有一个类似这样的 Dataframe 。但是,该时间被分配给每个用户的两个操作,Action_A and Action_B.
每个用户在每个SeqID上花费的总时间将是所有此类对的总和
对于第一个用户,它是5 + 3 [(2019-12-10 10:00:00 - 2019-12-10 10:05:00) + (2019-12-10 10:20:00 - 2019-12-10 10:23:00)]
因此,理想情况下,第一个用户为SeqID 1花费了8 mins
(而不是23 mins
)。
类似地,用户2花费了1 + 5 = 6 mins
如何使用pyspark计算此值?
data = [(("ID1", 15, "2019-12-10 10:00:00", "Action_A")),
(("ID1", 15, "2019-12-10 10:05:00", "Action_B")),
(("ID1", 15, "2019-12-10 10:20:00", "Action_A")),
(("ID1", 15, "2019-12-10 10:23:00", "Action_B")),
(("ID2", 23, "2019-12-10 11:10:00", "Action_A")),
(("ID2", 23, "2019-12-10 11:11:00", "Action_B")),
(("ID2", 23, "2019-12-10 11:30:00", "Action_A")),
(("ID2", 23, "2019-12-10 11:35:00", "Action_B"))]
df = spark.createDataFrame(data, ["ID", "SeqID", "Timestamp", "Action"])
df.show()
+---+-----+-------------------+--------+
| ID|SeqID| Timestamp| Action|
+---+-----+-------------------+--------+
|ID1| 15|2019-12-10 10:00:00|Action_A|
|ID1| 15|2019-12-10 10:05:00|Action_B|
|ID1| 15|2019-12-10 10:20:00|Action_A|
|ID1| 15|2019-12-10 10:23:00|Action_B|
|ID2| 23|2019-12-10 11:10:00|Action_A|
|ID2| 23|2019-12-10 11:11:00|Action_B|
|ID2| 23|2019-12-10 11:30:00|Action_A|
|ID2| 23|2019-12-10 11:35:00|Action_B|
+---+-----+-------------------+--------+
获得每一对的数据后,我可以对整个组求和(ID,SeqID)
预期输出(也可以是秒)
+---+-----+--------+
| ID|SeqID|Dur_Mins|
+---+-----+--------+
|ID1| 15| 8|
|ID2| 23| 6|
+---+-----+--------+
3条答案
按热度按时间ezykj2lf1#
下面是一个使用Higher-Order Functions(Spark〉=2.4)的可能解决方案:
步骤:
1.将所有时间戳收集到每个组
ID
、SeqID
的数组中,并按升序对其进行排序1.使用lambda函数
(x, i) => Double
对数组进行转换。其中x
是实际元素,i
是索引。对于数组中的每个时间戳,我们计算与下一个时间戳的diff。然后乘以(i+1)%2
,以便仅将diff作为2/2对(第一个与第二个,第三个与第四个,......)因为总是有两个动作。1.最后,我们聚合转换的结果数组,以求和所有元素。
输出量:
eagi6jfj2#
使用
flatMapValues
和rdd
执行此操作的一种可能方法(可能也很复杂)使用
data
变量这符合您描述的数据,但请检查它是否符合您的所有案例。
hiz5n14c3#
使用窗口函数的另一种可能的解决方案
Output