pyspark reduce key是一个元组值嵌套列表

时间:2016-05-09 09:57:42

标签: python mapreduce pyspark compound-key

我的问题如下:我正在解析用户交互,每次检测到交互时我发出((user1,user2),((date1,0),(0,1)))。这里的零点是相互作用的方向。

我无法弄清楚为什么我不能通过以下reduce函数减少此输出:

def myFunc2(x1,x2):
    return (min(x1[0][0],x2[0][0]),max(x1[0][0],x2[0][0]),min(x1[0][1],x2[0][1]),max(x1[0][1],x2[0][1]),x1[1][0]+x2[1][0],x1[1][1]+x2[1][1])

我的mapper(flatmap(myFunc))的输出是正确的:

  

((7401899,5678002),((1403185440.0,0),(1,0)))
  ((82628194,22251869),((0,1403185452.0),(0,1)))
  ((2162276,98056200),((1403185451.0,0),(1,0)))
  ((0509420,4827510),((1403185449.0,0),(1,0)))
  ((7974923,9235930),((1403185450.0,0),(1,0)))
  ((250259,6876774),((0,1403185450.0),(0,1)))
  ((642369,6876774),((0,1403185450.0),(0,1)))
  ((82628194,22251869),((0,1403185452.0),(0,1)))
  ((2162276,98056200),((1403185451.0,0),(1,0)))

但是正在运行

lines.flatMap(myFunc) \
              .map(lambda x: (x[0], x[1])) \
              .reduceByKey(myFunc2)

给我错误

  

return(min(x1 [0] [0],x2 [0] [0]),max(x1 [0] [0],x2 [0] [0]),min(x1 [0] [ 1],X 2 [0] [1]),最大值(X1 [0] [1],X 2 [0] [1])中,X 1 [1] [0] + X2 [1] [0]中,X 1 [1 ] [1] + X2 [1] [1])

     

TypeError:' int'对象没有属性' getitem '

我想我在把钥匙搞砸了,但我不知道为什么(我试图按照here重新设置关键元组,但同样的错误)

有些想法?非常感谢

1 个答案:

答案 0 :(得分:1)

好的,我认为这里的问题是你的内容索引太深,而且你的内容没有你想象的那么深。

我们来看看myFunc2

def myFunc2(x1,x2):
    return (min(x1[0][0],x2[0][0]),max(x1[0][0],x2[0][0]),min(x1[0][1],x2[0][1]),max(x1[0][1],x2[0][1]),x1[1][0]+x2[1][0],x1[1][1]+x2[1][1])

鉴于上述问题,输入数据将如下所示:

((467401899, 485678002), ((1403185440.0, 0), (1, 0)))

让我们继续并将该数据行分配给变量。

x = ((467401899, 485678002), ((1403185440.0, 0), (1, 0)))

当我们运行x[0]时会发生什么?我们得到(467401899, 485678002)。当我们运行x[1]时?我们得到((1403185440.0, 0), (1, 0))。这就是你的map声明正在做的事情,我相信。

好。这很清楚。

在您的函数myFunc2中,您有两个参数x1x2。这些对应于上面的变量:x1 = x[0] = (467401899, 485678002)x2 = x[1] = ((1403185440.0, 0), (1, 0))

现在让我们来看看函数中return语句的第一部分。

min(x1[0][0], x2[0][0])

所以,x1 = (467401899, 485678002)。凉。现在,x1[0]是什么?好吧,那是467401899。明显。可是等等!什么是x1[0][0]?您可以尝试在x1[0]获取项目的第0个索引,但x1[0]处的项目不是listtuple,而只是int 1}}。 <type 'int'>的对象没有名为getitem的方法。

总结一下:你正在深入研究那些没有深深嵌套的物体。仔细考虑您传递给myFunc2的内容,以及您的对象有多深。

我认为myFunc2的return语句的第一部分应如下所示:

return min(x1[0], x2[0][0])。您可以更深入地对x2进行索引,因为x2具有更深层嵌套的元组!

当我运行以下内容时,它的工作正常:

a = sc.parallelize([((7401899, 5678002), ((1403185440.0, 0), (1, 0))),
((82628194, 22251869), ((0, 1403185452.0), (0, 1))),
((2162276, 98056200), ((1403185451.0, 0), (1, 0))),
((1509420, 4827510), ((1403185449.0, 0), (1, 0))),
((7974923, 9235930), ((1403185450.0, 0), (1, 0))),
((250259, 6876774), ((0, 1403185450.0), (0, 1))),
((642369, 6876774), ((0, 1403185450.0), (0, 1))),
((82628194, 22251869), ((0, 1403185452.0), (0, 1))),
((2162276, 98056200), ((1403185451.0, 0), (1, 0)))])

b = a.map(lambda x: (x[0], x[1])).reduceByKey(myFunc2)

b.collect()

[((1509420, 4827510), ((1403185449.0, 0), (1, 0))),
 ((2162276, 98056200), (1403185451.0, 1403185451.0, 0, 0, 2, 0)),
 ((7974923, 9235930), ((1403185450.0, 0), (1, 0))), 
 ((7401899, 5678002), ((1403185440.0, 0), (1, 0))), 
 ((642369, 6876774), ((0, 1403185450.0), (0, 1))), 
 ((82628194, 22251869), (0, 0, 1403185452.0, 1403185452.0, 0, 2)),
 ((250259, 6876774), ((0, 1403185450.0), (0, 1)))]