从Pyspark中的RDD中提取序列

时间:2016-07-12 10:27:36

标签: python apache-spark pyspark

我正在尝试使用pyspark在Spark上为机器学习算法准备数据。我有一个包含纪元日期时间,ID和类(0或1)的RDD。它看起来如下所示:

rdd = sc.parallelize([Row(my_date=1465488788,id=4,my_class=1), Row(my_date=1465488790,id=5,my_class=0), Row(my_date=1465488801,id=23,my_class=1), Row(my_date=1465488805,id=23,my_class=1), Row(my_date=1465488809,id=5,my_class=0), Row(my_date=1465488810,id=32,my_class=0),Row(my_date=1465488826,id=38,my_class=1)])

此数据按日期排序。我想要做的是从这个数据中提取序列:这个RDD中同一时间窗口内的连续条目应该进入相同的序列。例如,20秒时间间隔内的所有数据应该在相同的序列中。如果上述数据集的序列时间窗口为20秒,我将需要创建以下3个序列:

[Row(my_seq=[4,5,23,23], my_class=1),Row(my_seq=[5,23,23,5,32], my_class=0),Row(my_seq=[5,32,38], my_class=1)]

班级编号应该是序列中最新的元素类。由于我的数据集非常大,我需要并行执行此操作。我试图通过在日期字段上对数据进行分组来实现这一点,但它没有起作用:

def createSequences(in_arr):
    in_arr = list(in_arr)
    seq_arr = []
    sorted_arr = []
    for e in in_arr:
        seq_arr.append(e["id"])
        sorted_arr.append(int(str(e["my_date"]) + str(e["my_class"])))
    sorted_arr.sort()
    if str(sorted_arr[-1])[-1] == "1":
        return Row(is_class = 1, seq = seq_arr, sorted_arr = sorted_arr)
    else:
        return Row(is_class = 0, seq = seq_arr, sorted_arr = sorted_arr)
offset = 1465488788
time_window = 20
grouped = clustered_logs.map(lambda row: (int((row["my_date"] - offset) / time_window), row)) \
                        .groupByKey() \
                        .map(lambda l: createSequences(l[1]))

它只是将同一窗口大小内的所有条目分组到相同的序列中,如果它们也在下一个第一个序列的时间窗口内,则我不能使用序列中的最新条目。如果有办法在Spark上实现这一点,你能帮我解决这个问题吗? 感谢...

1 个答案:

答案 0 :(得分:0)

time_window = 20
clustered_logs.groupBy(lambda x: (int(x /time_window), x.my_class) )\
    .map(lambda x: Row(my_class=x[0][1], my_seq=[ t.id for t in x[1]]) )
  • int(x /time_window)
  • 标识窗口
  • 按窗口和班级分组。分组键是元组(window, class)
  • 虽然此map x( (73274439, 1) , itrable<Row>)之类的元组。使用for理解迭代元组中的第二个值以创建列表。

参考:Scala doc RDD