Pyspark:根据类型对值进行操作

时间:2016-03-03 22:44:07

标签: python apache-spark pyspark rdd

我有这样的RDD:

[('a', ('H', 1)), ('b', (('H', 41), ('S', 1)))]

以便密钥可以包含tupletuple tuples个值作为值。这来自reduceByKey。 我需要执行一个简单的操作:将计数除以(H + S)的计数。 当S不存在时,就像第一项的情况一样,我将不得不返回0。 问题是将第一个案例(单tuple)与第二个案例(tuple中的tuples}隔离开来,以便我知道如何在map中操作。

我将如何进行?

1 个答案:

答案 0 :(得分:1)

一般来说,修复上游更有意义,但你可以尝试这样的例子:

from operator import truediv

def f(vs):
    try:
        d = dict(vs)
    except ValueError:
        d = dict([vs])

    s = sum(d.values())
    return truediv(d.get("S", 0), s) if s else float('nan')

rdd = sc.parallelize([('a', ('H', 1)), ('b', (('H', 41), ('S', 1)))])
rdd.mapValues(f).collect()

## [('a', 0.0), ('b', 0.023809523809523808)]

或者,如果您不介意外部依赖项,可以尝试使用multipledispatch

from multipledispatch import dispatch

@dispatch(tuple, tuple)
def f(h, s):
    try:
        return truediv(s[1], h[1] + s[1])
    except ZeroDivisionError:
        return float('nan')

@dispatch(str, int)
def f(x, y):
    return 0.0

rdd.mapValues(lambda args: f(*args)).collect()
## [('a', 0.0), ('b', 0.023809523809523808)]