Pyspark聚合 - 每个字段以不同的方式聚合

时间:2016-11-14 23:05:59

标签: python apache-spark

我有一些数据有四个基本字段:

  1. 字段1是数据的密钥
  2. 字段2应该是此字段的所有唯一值的集合
  3. 字段3是最小值(时间戳)
  4. 字段4是最大值(时间戳)
  5. 原始代码如下所示:

    data = (
        dataframe
        .rdd
        # flatten rows
        .flatMap(lambda x: x)
        # Parse JSON
        .flatMap(lambda x: encode_json(x))
        # Capture values
        .map(lambda x: [
            # Merge 'field1', 'field2' --> 'field1, field2'
            ','.join(_ for _ in [x.get('metadata_value'), x.get('field2')]),
            # Create pairing of low and high timestamps
            [x.get('low'), x.get('high')]
        ])
        # Aggregate into a list of low/high timestamps per 'field1, field2'
        .aggregateByKey(list(), lambda u, v: u + [v], lambda u1, u2: u1 + u2)
        # Flatten keys 'ip,guid' --> 'ip', 'guid'
        .map(lambda x: (x[0].split(',')[0], x[0].split(',')[1], x[1], sum(1 for _ in x[1])))
        # Reduce timestamps to single values:  [s1, e1], [s2, e2], ... --> s_min, e_max
        .map(lambda x: (x[0], x[1], min(_[0] for _ in x[2]), max(_[1] for _ in x[2]), x[3]))
    )
    

    原始输出如下所示:

    a | x012345 | 20160103 | 20160107
    a | x013579 | 20160101 | 20160106
    

    新输出应如下所示:

    a | {x012345,x013579} | 20160101 | 20160107
    

1 个答案:

答案 0 :(得分:1)

将此2个变换添加到当前输出,映射到一对RDD,并通过相应的操作(字典,最小值,最大值)减少每个字段。

data.map(lambda reg: (reg[0],[reg[1],reg[2],reg[3]])) .reduceByKey(lambda v1,v2: ({v1[0],v2[0]},min(v1[1],v2[1]), max(v1[2],v2[2])))