【问题标题】:A list as a key for PySpark's reduceByKey作为 PySpark 的 reduceByKey 的键的列表
【发布时间】:2015-10-02 22:47:02
【问题描述】:

我正在尝试对(([a,b,c], 1), ([a,b,c], 1), ([a,d,b,e], 1), ... 格式的数据调用pyspark 的reduceByKey 函数

似乎 pyspark 不会接受一个数组作为普通键中的键,通过简单地应用 .reduceByKey(add) 来减少值。

我已经尝试通过.map((x,y): (str(x),y))首先将数组转换为字符串,但这不起作用,因为将字符串后处理回数组太慢了。

有没有办法让 pyspark 使用数组作为键或使用其他函数快速将字符串转换回数组?

这是相关的错误代码

  File "/home/jan/Documents/spark-1.4.0/python/lib/pyspark.zip/pyspark/shuffle.py", line 268, in mergeValues
    d[k] = comb(d[k], v) if k in d else creator(v)
TypeError: unhashable type: 'list'
    enter code here

总结

输入:x =[([a,b,c], 1), ([a,b,c], 1), ([a,d,b,e], 1), ...]

期望的输出:y =[([a,b,c], 2), ([a,d,b,e], 1),...] 这样我就可以通过y[0][0][0]2 通过y[0][1] 访问a

【问题讨论】:

    标签: python apache-spark rdd pyspark


    【解决方案1】:

    试试这个:

    rdd.map(lambda (k, v): (tuple(k), v)).groupByKey()
    

    由于 Python 列表是可变的,这意味着不能被散列(不要提供__hash__ 方法):

    >>> a_list = [1, 2, 3]
    >>> a_list.__hash__ is None
    True
    >>> hash(a_list)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: unhashable type: 'list'
    

    另一方面,元组是不可变的,并提供 __hash__ 方法实现:

    >>> a_tuple = (1, 2, 3)
    >>> a_tuple.__hash__ is None
    False
    >>> hash(a_tuple)
    2528502973977326415
    

    因此可以用作键。同样,如果您想使用唯一值作为键,您应该使用frozenset

    rdd.map(lambda (k, v): (frozenset(k), v)).groupByKey().collect()
    

    而不是set

    # This will fail with TypeError: unhashable type: 'set'
    rdd.map(lambda (k, v): (set(k), v)).groupByKey().collect()
    

    【讨论】:

    • 感谢这对我对 spark 的总体理解有很大帮助
    • 不客气。顺便说一句,这不是特定于 Spark 的。当您使用纯 Python dictssets 时,同样适用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-31
    • 2015-12-09
    • 2018-08-07
    • 2015-07-02
    • 1970-01-01
    • 2015-10-17
    • 2015-07-06
    相关资源
    最近更新 更多