我有一个数组数组并将其传递给scala中的函数但出现错误

Posted

技术标签:

【中文标题】我有一个数组数组并将其传递给scala中的函数但出现错误【英文标题】:I have an array of array and passing it to a function in scala but getting errors 【发布时间】:2016-02-18 21:46:11 【问题描述】:

我需要实现一个距离搜索代码。我在 CSV 中的输入如下。

Proprty_ID,  lat,    lon
123,    33.84,  -118.39
234,    35.89,  -119.48
345,    35.34,  -119.39

我有一个半正弦公式,它采用 2 个坐标 (lat1, lon1), (lat2, lon2) 并返回距离。让我们说:

val Distance: Double = haversine(x1:Double, x2:Double, y1:Double, y2:Double)

我需要找出每个属性之间的距离。所以输出看起来像这样。

Property_ID1, Property_ID2, distance
123,123,0
123,234,0.1
123,345,0.6
234,234,0
234,123,0.1
234,345,0.7
345,345,0
345,123,0.6
345,234,0.7

如何在 Scala 中实现这一点?

import math._

object Haversine 
   val R = 6372.8  //radius in km

   def haversine(lat1:Double, lon1:Double, lat2:Double, lon2:Double)=
      val dLat=(lat2 - lat1).toRadians
      val dLon=(lon2 - lon1).toRadians

      val a = pow(sin(dLat/2),2) + pow(sin(dLon/2),2) * cos(lat1.toRadians) * cos(lat2.toRadians)
      val c = 2 * asin(sqrt(a))
      R * c
   

   def main(args: Array[String]): Unit = 
      println(haversine(36.12, -86.67, 33.94, -118.40))
  


class SimpleCSVHeader(header:Array[String]) extends Serializable 
  val index = header.zipWithIndex.toMap
  def apply(array:Array[String], key:String):String = array(index(key))


val lat1=33.84
val lon1=-118.39
val csv = sc.textFile("file.csv") 
val data = csv.map(line => line.split(",").map(elem => elem.trim)) 
val header = new SimpleCSVHeader(data.take(1)(0)) // we build our header with the first line
val rows = data.filter(line => header(line,"lat") != "lat") // filter the header out

// I will do the looping for all properties here but I am trying to get the map function right for one property at least
val distances = rows.map(x => haversine(x.take(1)(0).toDouble,x.take(1)(1).toDouble, lat1,lon1)`

现在这应该给我所有属性与(lat1, lon1) 的距离。我知道这是不对的,但我无法从这里思考。

【问题讨论】:

到目前为止,您写过什么或尝试过什么?我们很乐意提供帮助,但为您编写代码不是本网站的目的。相反,如果您要展示您编写但无法正常工作的代码,我们可以帮助您使其正常工作。 这是我目前得到的代码。 【参考方案1】:

我会尝试将其分解为多个步骤。给定数据如下:

  val rows = List(Array("123", "33.84", "-118.39"),
                  Array("234", "35.89", "-119.48"),
                  Array("345", "35.34", "-119.39"))

先转换类型:

  val typed = rows.map case Array(id, lat, lon) => (id, lat.toDouble, lon.toDouble)

然后生成组合:

  val combos = for 
    a <- typed
    b <- typed
   yield (a,b)

然后为每个组合生成一个输出行:

  combos.map case ((id1, lat1, lon1), (id2, lat2, lon2)) 
     => id1 + "," + id2 + "," + haversine(lat1, lon1, lat2, lon2) foreach println

【讨论】:

非常感谢 DNA。这是工作。但是你知道我是否可以在 Spark 中的 RDD 上应用相同的功能。我正在从 CSV 创建输入数据的 RDD。但它在 typed.collect() 上失败了。 我建议您使用当前的 Spark 代码提出一个新问题,以便我们更好地了解问题所在。

以上是关于我有一个数组数组并将其传递给scala中的函数但出现错误的主要内容,如果未能解决你的问题,请参考以下文章

将变量传递给一个数组中对象的函数

Scala:无法将数组传递给需要 Seq 或 Iterable 的函数

如何将Mac地址转换为十六进制并将其传递给java中的字节数组

如何正确传递带有指向函数的指针的数组?

C,如何将多维数组传递给 CLR/类库项目中的函数

指针数组内容在传递给 C 中的函数时被擦除