如何使用Scala和Spark从数组中选择非顺序子集元素?

Cli*_*der 6 arrays scala apache-spark

在Python中,我就是这样做的.

>>> x
array([10,  9,  8,  7,  6,  5,  4,  3,  2])
>>> x[np.array([3, 3, 1, 8])]
array([7, 7, 9, 2])
Run Code Online (Sandbox Code Playgroud)

这在Scala Spark shell中不起作用:

scala> val indices = Array(3,2,0)
indices: Array[Int] = Array(3, 2, 0)

scala> val A = Array(10,11,12,13,14,15)
A: Array[Int] = Array(10, 11, 12, 13, 14, 15)

scala> A(indices)
<console>:28: error: type mismatch;
 found   : Array[Int]
 required: Int
              A(indices)
Run Code Online (Sandbox Code Playgroud)

foreach方法也不起作用:

scala> indices.foreach(println(_))
3
2
0

scala> indices.foreach(A(_))
<no output>
Run Code Online (Sandbox Code Playgroud)

我想要的是B的结果:

scala> val B = Array(A(3),A(2),A(0))
B: Array[Int] = Array(13, 12, 10)
Run Code Online (Sandbox Code Playgroud)

但是,我不想像那样对它进行硬编码,因为我不知道索引的长度或内容是多少.

Jus*_*ony 7

我能想到的最简洁的方法是翻转你的心智模型并将指数放在首位:

indices map A
Run Code Online (Sandbox Code Playgroud)

并且,我可能建议使用lift返回Option

indices map A.lift
Run Code Online (Sandbox Code Playgroud)


Ben*_*ich 7

您可以使用mapon indices,它根据映射lambda将每个元素映射到一个新元素.注意,在Array,使用apply方法获得索引处的元素:

indices.map(index => A.apply(index))
Run Code Online (Sandbox Code Playgroud)

你可以离开apply:

indices.map(index => A(index))
Run Code Online (Sandbox Code Playgroud)

您还可以使用下划线语法:

indices.map(A(_))
Run Code Online (Sandbox Code Playgroud)

当你遇到这样的情况时,你甚至可以不用下划线:

indices.map(A)
Run Code Online (Sandbox Code Playgroud)

您可以使用备用空格语法:

indices map A
Run Code Online (Sandbox Code Playgroud)

您试图使用foreach,返回Unit,并仅用于副作用.例如:

indices.foreach(index => println(A(index)))
indices.map(A).foreach(println)
indices map A foreach println
Run Code Online (Sandbox Code Playgroud)