Spark的笛卡尔函数会产生不良结果

时间:2016-02-29 19:48:54

标签: apache-spark pyspark cartesian

我在Spark的笛卡尔函数中遇到了不良结果。小数据集无法重现;它只会持续存在大型数据集。

例如:

小数据集

a = sc.parallelize([1, 2, 3, 4, 5])
b = sc.parallelize([(100, 150), (200, 250), (300, 350), (400, 450), (500, 550)])
c = a.cartesian(b)
print c.collect()
print c.count()
  

print c.collect()

     
    

[(1,(100,150)),(1,(200,250)),(2,(100,150)),(2,(200,250)),(1,(300, 350)),(1,(400,450)),(2,(300,350)),(2,(400,450)),(1,(500,550)),(2,(500, 550)),(3,(100,150)),(3,(200,250)),(4,(100,150)),(4,(200,250)),(5,(100, 150)),(5,(200,250)),(3,(300,350)),(3,(400,450)),(4,(300,350)),(4,(400, 450)),(3,(500,550)),(4,(500,550)),(5,(300,350)),(5,(400,450)),(5,(500, 550))]

  
     

print c.count()

     
    

25

  

由于“a”有5个元素而“b”有5个元素,因此两者的笛卡尔积是25个元素。但是,对于大型数据集,笛卡尔的大小小于预期值。

大型数据集

x = sc.parallelize([1, 2, 3, 4, 5])
print x.collect()
"""
y is a RDD in the same format as b.
y.count() == 19475211
""" 
print y.take(5)

z = x.cartesian(y)
print z.take(5)
print z.count()
  

print x.collect()

     
    

[(1,2,3,4,5)]

  
     

print y.take(5)

     
    

[(5120,2560),(5120,408),(5120,520),(5120,3500),(5120,2060)]

  
     

print z.take(5)

     
    

[(1,(5120,2560)),(1,(5120,408)),(1,(5120,520)),(5120,(3500,1)),(5120,(2060, 1))]

  
     

print z.count()

     
    

7451200

  

如果您注意到大数据集,当您采用x和y的笛卡儿时,z的第4个元素是(5120,(3500,1))而不是(1,(5120,3500))。 z的第五个元素是(5120,(2060,1))而不是(1,(5120,2060))。

此外,z的大小为7451200而不是19475211 * 5 = 97376055.

导致此问题的原因是什么?什么是防止这种情况发生的解决方案?

1 个答案:

答案 0 :(得分:0)

虽然我还没弄清楚为什么会这样,但我确实解决了这个问题。我首先播放x列表然后在y上执行平面地图操作。结果z是我期望的结果。

x = sc.broadcast([1, 2, 3, 4, 5])
z = y.flatMap(lambda (y_1, y_2): [(x_elt, (y_1, y_2)) for x_elt in x.value])