Apache spark 查找给定单个门店位置的最近门店+;pyspark中的最大广播变量大小是多少?
我正在尝试读取一个文件,其中包含所有杂货店的RDD。目标是为给定的杂货店找出最近的500家商店,并进行一些处理。 例如,如果一家商店被占领,我必须找到该城市的所有商店。如果我在RDD上进行映射,我将获得转换函数的单个存储。我如何获得该功能中的所有存储 片段Apache spark 查找给定单个门店位置的最近门店+;pyspark中的最大广播变量大小是多少?,apache-spark,pyspark,pyspark-sql,Apache Spark,Pyspark,Pyspark Sql,我正在尝试读取一个文件,其中包含所有杂货店的RDD。目标是为给定的杂货店找出最近的500家商店,并进行一些处理。 例如,如果一家商店被占领,我必须找到该城市的所有商店。如果我在RDD上进行映射,我将获得转换函数的单个存储。我如何获得该功能中的所有存储 片段 def getNearestStores(store): stores_city = stores.filter("city="+store.city) return (store.id,stores_city.count()
def getNearestStores(store):
stores_city = stores.filter("city="+store.city)
return (store.id,stores_city.count())
stores = sc.textFile("stores.json").map(getNearestStores).count()
这是简单的代码片段。Stores.json是一个巨大的文件
1) 我如何在getNearestStores函数中使用stores.json获得最近的500个存储
2) PySpark中的最大广播变量大小是多少?~2GB是广播变量的最大大小,因为任何广播变量在序列化过程中变为java字节数组,并且java数组具有max size Integer.max_值 这些是与PySpark 2.x相关的较老(类似)的问题 跟踪此问题的JIRA: 编辑: 使用SparkSession+DataFrame(因为这是PySpark-2.x)按如下方式进行连接
from pyspark.sql import SparkSession
spark = SparkSession \
.builder \
.appName("Python Spark SQL basic example") \
.config("spark.some.config.option", "some-value") \
.getOrCreate()
df = spark.read.json("stores.json")
nearest_stores_df = df.join(df, "city") # self-join
对你的评论做出回应,详细说明你真正想要实现的目标 我在spark中不使用python,但在scala中,我会这样开始。大多数重要的东西都是特定于spark的,应该很容易转换为python 商店类别:
class Store(val id: String,
val city: String,
val lat: Double,
val lon: Double) extends Haversine {
// distance in km
def distance(that: Store) = {
val radius = 6371 // earth in km
val dlat = toRadians(that.lat - this.lat)
val dlon = toRadians(that.lon - this.lon)
val a = sin(dlat/2) * sin(dlat/2) +
cos(toRadians(this.lat)) * cos(toRadians(that.lat)) * sin(dlon/2) * sin(dlon/2)
val c = 2 * atan2(sqrt(a), sqrt(1-a))
val d = radius * c
d
}
}
既然您使用的是python,我将把JSON解析到类中留给您
// read JSON into class Store
val rdd_store: RDD[Store] = ???
这是最重要的部分。。。我的会像这样直到我把它调试好。。。但是如果我真的要使用它的话,我会把难以理解的部分转移到助手函数或类中
// result
val rdd2: RDD[(Store, List[Store])] = {
rdd_store
.keyBy(_.city) // RDD[(city, store)] (one row per store)
.groupByKey // RDD[(city, all stores in city)] (one row per city)
.flatMap { case (city, iter_stores) =>
iter_stores.map(one_store => {
// up-to 500 closest stores in same city as 'one_store'
val top500: List[Store] = {
iter_stores
.toList
.map { s =>
val dist = one_store distance s
(dist, s)
}
}.sorted.take(500).map{ case (dist, that_store) => that_store }
// result
(one_store, top500)
})
} // RDD[(store, list of top 500 stores in same city)] (one row per store)
}
好啊这是有道理的。但是你知道我该如何解决上述问题吗?是的。1) 使用SparkSession+DataFrame或Dataset,2)为门店创建一个表,并在city上进行连接,而不是广播的高成本如果我从代码中理解了这项任务,那就是为每个门店获取同一城市中所有门店的计数。。。如果这是对的,我不会使用广播变量。。。我会在RDD[商店]上执行类似的操作,以获得RDD[(商店id,计算同一城市的商店)]
rdd.keyBy(u.city).groupByKey.flatMap{case(city,iter_stores)=>iter_stores.map(one_store=>(one_store.id,iter_stores.size))}
@kmh这不仅仅是计数。还需要执行其他处理。这里是一个完整的用例:对于每个商店,在同一个城市中找到附近的500家商店,并对这500家商店进行一些处理。最终的结果是(商店,[500家附近的加工商店]),我仍然会做一个keyBy,groupByKey,flatMap来到达那里。我还想更改您问题的标题,因为这实际上与广播变量max size.Ok无关。这真的很有帮助。非常感谢你。请给我另一个建议:如果这个城市没有500家店铺,我有另一个文件,上面写着去500家店铺要选哪个城市。我怎么能那样做呢。