我刚刚开始使用Spark,但遇到的问题是我真的不知道该如何处理。
我的输入是以下格式的RDD:
[(u'7362', (u'2016-06-29 09:58:35', 0)), (u'8600', (u'2016-06-29 20:47:27', 1)), (u'f9f8', (u'2016-07-01 00:48:55', 2)), (u'c6c9', (u'2016-07-04 20:29:19', 3)), (u'218b', (u'2016-07-05 20:54:45', 4))]
所以结构是
[(user_id, (time_stamp, index))]
我需要做的是返回列表列表或元组列表。
如果我们以表格式查看RDD,这会更容易。用更“经典”的表格形式说出上述rdd。
[(u'7362', (u'2016-06-29 09:58:35', 0)),
(u'8600', (u'2016-06-29 20:47:27', 1)),
(u'7362', (u'2016-07-01 00:48:55', 2)),
(u'c6c9', (u'2016-07-04 20:29:19', 3)),
(u'8600', (u'2016-07-05 20:54:45', 4))]
我需要首先按用户将此RDD分组,所以最终我将获得三个RDD(每个用户一个,非重复用户一个)。
[(u'7362', (u'2016-06-29 09:58:35', 0)),
(u'7362', (u'2016-07-01 00:48:55', 2))]
[(u'8600', (u'2016-06-29 20:47:27', 1)),
(u'8600', (u'2016-07-05 20:54:45', 4))]
[(u'c6c9', (u'2016-07-04 20:29:19', 3))]
现在,对于仅包含一个user_id(前两个)的“表”,我需要计算与上一行的每一行的时间差,以及与每个先前索引的每个索引的时差(考虑到这些“表”有很多多于2行)。 这将给出类似表:
[(u'7362', (35, 2)), (u'7362', (21, 1)), (u'7362', (12, 3)), (u'7362', (41, 2)), (u'7362', (46, 2)), (u'7362', (31, 1)), (u'7362', (97, 3)) ...]
对于第一个user_id
[(u'8600', (78, 2)), (u'8600', (43, 1)), (u'8600', (99, 3)), (u'8600', (3, 2)), (u'8600', (15, 2)), (u'8600', (42, 1)), (u'8600', (11, 3)) ...]
,依此类推,对于所有用户,对于所有行,格式为[(user_idx, (dt=t2-t1, didx=idx2-idx1))]
且dt
和didx
是通过从当前行值中减去先前的行值而得出的。
最后,当我拥有以上所有表时,对于每个用户,我想将它们分组为一个嵌套列表,如下所示:
[[1, [21, 31, 43, 42]], [2, [35, 41, 46, 78, 3, 15]], [3, [12, 97, 99, 11]]]
所以最终的格式是[[didx, [dt1, dt2 ...]]
,在这里我不再关心user_ids了,只是所有用户的索引以及与同一索引相关的每次时间差。
我试图尽力清楚地解释问题,但是,就像我说的那样,我真的刚刚开始使用Spark,我知道这里没有真正的表格。
答案 0 :(得分:1)
当您通过userId分组时,这不会导致多个RDD,而是一个RDD [(UserId,list [(time,index)]]形式的RDD。因此,在这种情况下,我将执行groupBy,然后将用户列表处理为格式,然后按照您所说的对didx进行分组,最后从RDD中收集结果以列出。
# assume each user has more than one event
# if this ^ assumption is incorrect, you could filter the RDD before processing to get rid of users
# with only one event
# also, assume timesteps can be subtracted (there are libraries for this)
def process(indexedTimes):
num_times = len(indexedTimes)
new_list = []
for i in range(1,num_times):
new_list.append((indexedTimes[i][1]-indexedTimes[i-1][1],datediff(indexedTimes[i][0]-indexedTimes[i-1][0])))
return new_list
data # RDD[(userId, (timestep, index))]
.groupByKey # now RDD[(userId, list[(timestep, index)])]
.flatMap(lambda userList: process(list(userList[1]))) # now RDD[(didx, dt)]
.groupByKey # now RDD[(didx, list(dt))]
.collect # get elements in final list instead of RDD