2015-11-11 25 views
2

我在Spark Scala中使用了笛卡尔变换。如果我输入由4个元素(可以是数字/符号/元组)说Scala中的笛卡尔变换中的显式排序Spark

var myRDD=sc.parallelize(Array("e1","e2","e3","e4")) 

myRDD.cartesian(myRDD)会产生对所有可能的组合,但不一定秩序。什么是聪明的方式来获得这些对订单?即

Array((e1,e1), (e1,e2), (e1,e3), (e1,e4), (e2,e1), (e2,e2), (e2,e3), (e2,e4), (e3,e1), (e3,e2), (e3,e3), (e3,e4), (e4,e1), (e4,e2), (e4,e3), (e4,e4)) 
+3

你需要什么样的顺序?更重要的是,为什么你需要这个命令? –

+0

我有一组坐标(x,y,z),我需要计算它们之间的RMSD距离。我使用笛卡儿变换来获得坐标对前。 ((C1,C2),(C1,C3),...)。顺序很重要,所以我知道哪个距离属于哪一对。 –

+0

我认为最好的方法是用索引压缩每个点,以便稍后识别它们,而不是排序,这将需要您将所有数据收集到主数据库中。想想这个,可能的组合将是巨大的!他们可能不适合记忆! –

回答

0

您是否尝试过sorted功能?似乎是由它的第一个成员排序元组,然后通过第二等:

scala> val a = Array((1, 1), (3, 3), (2, 2)) 
a: Array[(Int, Int)] = Array((1,1), (3,3), (2,2)) 

scala> a.sorted 
res1: Array[(Int, Int)] = Array((1,1), (2,2), (3,3)) 

scala> val a = Array((1, 2), (3, 1), (2, 3)) 
a: Array[(Int, Int)] = Array((1,2), (3,1), (2,3)) 

scala> a.sorted 
res2: Array[(Int, Int)] = Array((1,2), (2,3), (3,1)) 

scala> val a = Array((1, 2), (3, 1), (1, 1)) 
a: Array[(Int, Int)] = Array((1,2), (3,1), (1,1)) 

scala> a.sorted 
res3: Array[(Int, Int)] = Array((1,1), (1,2), (3,1)) 
+2

OP使用Spark(尽管在他们的例子中是Array)。 RDDs没有'.sorted'(但他们确实有'.sortBy',它可以完成这项工作。昂贵的) –

+0

谢谢。我会试试这个。如果排序很昂贵,我想我可以使用列表理解来获得对。 –

+0

我认为这种方法非常不合适,因为要求您在主服务器(如果使用集群)中收集数据,并在执行过程中遇到可能的问题。 –

2

如果您需要的是能够识别每一个点(这样你就可以决定对点和他们的L2距离)因此您真正需要的是在RDDDataFrame中的每个条目中添加id

如果你想使用RDD,我推荐的做法是:

myRDD = sc.parallelize([(0, (0.0, 0.0)), (1, (2.0, 0.0)), 
         (2, (-3.0, 2.0)), (3, (-6.0, -4.0))]) 

combinations = myRDD.cartesian(myRDD).coalesce(32) 

distances = combinations\ 
    .filter(lambda (x, y): x[0] < y[0])\ 
    .map(lambda ((id1, (x1, y1)), (id2, (x2, y2))): (id1, id2, ((x1 - x2) ** 2 + (y1 - y2) ** 2) ** 0.5)) 

distances.collect()