Spark -嵌套RDD操作



我有两个rdd说

   rdd1 = 
id            | created     | destroyed | price   
1            | 1            | 2            | 10        
2            | 1            | 5            | 11       
3            | 2            | 3            | 11        
4            | 3            | 4            | 12        
5            | 3            | 5            | 11       
rdd2 =
[1,2,3,4,5] # lets call these value as timestamps (ts)

rdd2基本上是使用range(initial_value, end_value, interval)生成的。这里的参数可以有所不同。大小可与rdd1相同或不同。这个想法是使用过滤标准根据rdd2的值从rdd1获取记录到rdd2(从rdd1获取的记录可以重复,正如您在输出中看到的)

过滤条件rdd1。已创建<= ts <rdd1.destroyed)>

预期输出:

ts             | prices  
1              | 10,11       # i.e. for ids 1,2 of rdd1      
2              | 11,11       # ids 2,3
3              | 11,12,11    # ids 2,4,5 
4              | 11,11       # ids 2,5

现在我想根据使用RDD2的键的一些条件来过滤RDD1。(如上所述)并返回RDD2的键和RDD1的过滤结果的连接结果

所以我做了:

rdd2.map(lambda x : somefilterfunction(x, rdd1))  
def somefilterfunction(x, rdd1):
    filtered_rdd1 = rdd1.filter(rdd1[1] <= x).filter(rdd1[2] > x)
    prices = filtered_rdd1.map(lambda x : x[3])
    res = prices.collect()
    return (x, list(res))

得到:

异常:似乎您正在尝试广播RDD或从操作或转换中引用RDD。抽样转换并且操作只能由驱动程序调用,而不能在其他程序中调用转换;例如,rdd1。Map (lambda x: rdd2.values.count() *X)无效,因为值转换和计数操作不能在rdd1内部执行。映射转换。更多的参考SPARK-5063。

我尝试使用groupBy,但是因为这里rdd1的元素可以一次又一次地重复,而不是分组,我理解rdd1的每个元素只会在某个特定的槽中出现一次。

现在唯一的方法是使用普通的for循环,并进行过滤,并在最后连接所有内容。

有什么建议吗?

由于您使用了常规范围,因此根本没有理由创建第二个RDD。您可以简单地为每条记录生成特定范围内的值:

from __future__ import division # Required only for Python 2.x
from math import ceil
from itertools import takewhile
rdd1 = sc.parallelize([
    (1, 1, 2, 10),        
    (2, 1, 5, 11),       
    (3, 2, 3, 11),        
    (4, 3, 4, 12),        
    (5, 3, 5, 11),  
])

def generate(start, end, step):
    def _generate(id, created, destroyed, price):
        # Smallest ts >= created
        start_for_record = int(ceil((created - start) / step) * step + start)
        rng = takewhile(
            lambda x: created <= x < destroyed,
            xrange(start_for_record, end, step)) # In Python 3.x use range
        for i in rng:
            yield i, price
    return _generate
result = rdd1.flatMap(lambda x: generate(1, 6, 1)(*x)).groupByKey()

和结果:

result.mapValues(list).collect()
## [(1, [10, 11]), (2, [11, 11]), (3, [11, 12, 11]), (4, [11, 11])]

相关内容

  • 没有找到相关文章