私は、約20,000の緯度、経度座標のリストを循環し、各点から基準点までの距離を計算する、非常に単純なpythonルーチンを持っています。
def compute_nearest_points( lat, lon, nPoints=5 ):
"""Find the nearest N points, given the input coordinates."""
points = session.query(PointIndex).all()
oldNearest = []
newNearest = []
for n in xrange(nPoints):
oldNearest.append(PointDistance(None,None,None,99999.0,99999.0))
newNearest.append(obj2)
#This is almost certainly an inappropriate use of deepcopy
# but how SHOULD I be doing this?!?!
for point in points:
distance = compute_spherical_law_of_cosines( lat, lon, point.avg_lat, point.avg_lon )
k = 0
for p in oldNearest:
if distance < p.distance:
newNearest[k] = PointDistance(
point.point, point.kana, point.english, point.avg_lat, point.avg_lon, distance=distance
)
break
else:
newNearest[k] = deepcopy(oldNearest[k])
k += 1
for j in range(k,nPoints-1):
newNearest[j+1] = deepcopy(oldNearest[j])
oldNearest = deepcopy(newNearest)
#We're done, now print the result
for point in oldNearest:
print point.station, point.english, point.distance
return
私は当初、まったく同じアプローチを使用してこれを C で作成しました。そこでは問題なく動作し、nPoints<=100 の場合は基本的に瞬時です。SqlAlchemy を使って他のことをしたかったので、Python に移植することにしました。
私は最初にメソッドをペッパーするディープコピーステートメントなしでそれを移植しました。これにより、結果が「奇妙」または部分的に正しくなくなりました。それでも、C バージョンとほぼ同じ速さでした。
deepcopy 呼び出しが追加されたので、ルーチンは正しく機能しますが、極端にパフォーマンスが低下し、同じ機能を実行するのに数秒かかります。
これはかなり一般的な仕事のように思えますが、私は明らかに Pythonic の方法でそれを行っていません。正しい結果が得られるが、どこにでもディープコピーを含める必要がないようにするには、どうすればよいですか?
編集:
私ははるかにシンプルで高速なソリューションを見つけました。
def compute_nearest_points2( lat, lon, nPoints=5 ):
"""Find the nearest N points, given the input coordinates."""
points = session.query(PointIndex).all()
nearest = []
for point in points:
distance = compute_spherical_law_of_cosines( lat, lon, point.avg_lat, point.avg_lon )
nearest.append(
PointDistance(
point.point, point.kana, point.english, point.avg_lat, point.avg_lon, distance=distance
)
)
nearest_points = sorted(nearest, key=lambda point: point.distance)[:nPoints]
for item in nearest_points:
print item.point, item.english, item.distance
return
したがって、基本的には、入力の完全なコピーを作成し、新しい値 (基準点からの距離) を追加するだけです。次に、結果のリストに「sorted」を適用し、ソート キーが PointDistance オブジェクトの距離プロパティになるように指定します。
理由はよくわかりませんが、これは deepcopy を使用するよりもはるかに高速です。私はそれが効率的な C 実装の python の「ソート済み」にかかっていると思いますか?