【发布时间】:2017-02-28 22:52:24
【问题描述】:
很难理解这一点。
我有两个组成光纤网络的 CSV:一个用于纬度,一个用于经度。这些是从 KMZ 文件中提取的,由于 KMZ 构建不佳,两个 CSV 都包含 170k 行。
我有一个潜在客户的 CSV,我想将其与光纤网络进行比较。如果最小距离(使用 Haversine 公式计算)小于 5280 英尺,则会将其打印到输出 csv 文件中。
过去我在这方面取得了成功,当时没有那么多纬度/经度对:过去是 20k,但现在我们有 170k。输出的 csv 文件变得非常庞大,您可以想象:300 万行并且还在增加。
然后我要做的是检查(通常使用 MySQL MIN() 函数,但我确信有更好的方法)返回每个地址和按地址分组的最小距离:因为你真的只关心关于每个地址的最小距离。您不希望每个地址有多行。
require 'csv'
require 'haversine'
#this could be put into one file, works as is
fib_lat = CSV.read("swfl_fiber_lat.csv")
fib_long = CSV.read("swfl_fiber_long.csv")
#use zip to read both arrays at the same time
fib_coords = fib_lat.map(&:last).zip(fib_long.map(&:last))
#multiple column CSV with customer data, headers turned on
customers = CSV.read("swfl_1a_geocoded.csv", headers:true)
CSV.open('swfl-output-data-within-1mile.csv','w', :write_headers=> true, :headers => ['First Name','Last Name','Latitude','Longitude','Feet to Fiber','Address','City','State','Zip','County','Company','Title Code Description','PrimarySIC6 Description','Business Status Code Description','Phone Number','Tollfree Phonenumber','EmployeeSize Location Description','Sales Volume Location Decode','Telecommunications Expense','Email Address']) do |csv_object|
fib_coords.each do |fib_lat, fib_long|
customers.each do |cust|
if (Haversine.distance(cust[2].to_f, cust[3].to_f, fib_lat.to_f, fib_long.to_f).to_feet < 5280)
data_out = ["#{cust[0]},#{cust[1]},#{cust[2].to_f},#{cust[3].to_f}, #{Haversine.distance(cust[2].to_f, cust[3].to_f, fib_lat.to_f, fib_long.to_f).to_feet.round(2)},#{cust[5]},#{cust[6]},#{cust[7]},#{cust[8]},#{cust[9]},#{cust[10]},#{cust[11]},#{cust[12]},#{cust[13]},#{cust[14]},#{cust[15]},#{cust[16]},#{cust[17]},#{cust[18]}"]
csv_object << data_out
end
end
end
end
我正在想办法返回客户(可能使用 .uniq arr#min 并且仅使用每个客户的最小地址,而不将其推入输出 CSV。然后,如果确实存在低于 5,280 的距离和关联的客户,仅将其放入输出 CSV 数组中。
关于伪代码:如果距离是每个客户的最小值,请确保客户价值是唯一的,然后将其推入输出 CSV。只是没有 100% 了解如何在我的一系列循环中实现这一点。
任何和所有的见解都是值得赞赏的。
【问题讨论】: