質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

1回答

4477閲覧

緯度経度間の距離を求める関数のベクトル化

yositigu

総合スコア17

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2018/06/13 11:27

下記のプログラムを処理高速化のためにベクトル化した場合の処理を教えてください。
下記の処理は2点の緯度経度の点の距離を求めるプログラムです。

python

1def CAL_PHI(ra,rb,lat): 2 return atan(rb/ra*tan(lat)) 3 4def CAL_RHO(Lat_A,Lon_A,Lat_B,Lon_B): 5 ra=6378.140 # equatorial radius (km) 6 rb=6356.755 # polar radius (km) 7 F=(ra-rb)/ra # flattening of the earth 8 rad_lat_A=radians(Lat_A) 9 rad_lon_A=radians(Lon_A) 10 rad_lat_B=radians(Lat_B) 11 rad_lon_B=radians(Lon_B) 12 pA=CAL_PHI(ra,rb,rad_lat_A) 13 pB=CAL_PHI(ra,rb,rad_lat_B) 14 xx=acos(sin(pA)*sin(pB)+cos(pA)*cos(pB)*cos(rad_lon_A-rad_lon_B)) 15 c1=(sin(xx)-xx)*(sin(pA)+sin(pB))**2/cos(xx/2)**2 16 c2=(sin(xx)+xx)*(sin(pA)-sin(pB))**2/sin(xx/2)**2 17 dr=F/8*(c1-c2) 18 rho=ra*(xx+dr) 19 return rho

現在は、

python

1distance = CAL_RHO(base_points[i][0],base_points[i][1],points[j][0],points[j][1])

みたいな感じで実行しているのですが、こちらを

python

1def CAL_RHO(p1, p2):

として渡して処理し、ベクトルとして扱うロジックに変更したいです。
処理の高速化を行いたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

coco_bauer

2018/06/13 12:07

「ベクトルとして扱う」とは何をする事ですか? 引数の渡し方を変えても、結局二組の緯度・経度のペアな訳ですから計算式は変わらない(処理速度も変わらない)と思います。
guest

回答1

0

基本的にnp.を前につけることと、
https://docs.scipy.org/doc/numpy-1.14.0/reference/generated/numpy.arccos.html
みたいな公式ドキュメントを引けばできます。

python

1import numpy as np 2 3np.random.seed(2018) 4points = np.random.random((100000, 2))*10 5base_points = np.random.random((100, 2))*10 6 7def vCAL_RHO(p1s, p2): 8 ra = 6378.140 9 rb = 6356.755 10 F = (ra - rb)/ra 11 rad_A = np.radians(p1s) 12 rad_B = np.radians(p2) 13 pA = np.arctan(rb/ra*np.tan(rad_A[:, 0])) 14 pB = np.arctan(rb/ra*np.tan(rad_B[0])) 15 xx = np.arccos(np.sin(pA)*np.sin(pB) + np.cos(pA)*np.cos(pB)*np.cos(rad_A[:, 1] - rad_B[1])) 16 c1 = (np.sin(xx) - xx)*(np.sin(pA) + np.sin(pB))**2/np.cos(xx/2)**2 17 c2 = (np.sin(xx) + xx)*(np.sin(pA) - np.sin(pB))**2/np.sin(xx/2)**2 18 dr = F/8*(c1 - c2) 19 rho = ra*(xx + dr) 20 return rho 21 22from math import radians, sin, cos, acos, tan, atan 23def CAL_PHI(ra,rb,lat): 24 return atan(rb/ra*tan(lat)) 25 26def CAL_RHO(Lat_A,Lon_A,Lat_B,Lon_B): 27 ra=6378.140 # equatorial radius (km) 28 rb=6356.755 # polar radius (km) 29 F=(ra-rb)/ra # flattening of the earth 30 rad_lat_A=radians(Lat_A) 31 rad_lon_A=radians(Lon_A) 32 rad_lat_B=radians(Lat_B) 33 rad_lon_B=radians(Lon_B) 34 pA=CAL_PHI(ra,rb,rad_lat_A) 35 pB=CAL_PHI(ra,rb,rad_lat_B) 36 xx=acos(sin(pA)*sin(pB)+cos(pA)*cos(pB)*cos(rad_lon_A-rad_lon_B)) 37 c1=(sin(xx)-xx)*(sin(pA)+sin(pB))**2/cos(xx/2)**2 38 c2=(sin(xx)+xx)*(sin(pA)-sin(pB))**2/sin(xx/2)**2 39 dr=F/8*(c1-c2) 40 rho=ra*(xx+dr) 41 return rho 42 43centers = [] 44for _ in range(3): 45 mcnt = -1 46 best = -1 47 mcovered = None 48 for i, bp in enumerate(base_points): 49 dist = vCAL_RHO(points, bp) 50 assert dist[0] == CAL_RHO(points[0, 0], points[0, 1], bp[0], bp[1]) 51 covered = dist < 50. 52 cnt = np.sum(covered) 53 if cnt > mcnt: 54 mcovered = covered 55 mcnt = cnt 56 best = i 57 centers.append(base_points[best]) 58 points = points[np.logical_not(mcovered)] 59print(best) 60print(mcnt) 61print(points.shape) 62 63centers = np.array(centers) 64import matplotlib.pyplot as plt 65skip = 1 66fig, ax = plt.subplots(dpi=100) 67ax.set_aspect('equal') 68ax.scatter(points[::skip, 0], points[::skip, 1], s=10) 69ax.scatter(centers[:, 0], centers[:, 1], c='red', s=15**2) 70plt.show()

投稿2018/06/13 12:51

mkgrei

総合スコア8560

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yositigu

2018/06/14 01:59

ありがとうございます。 実際には ``` query = text("""select lat,lon from sample.table""") result = engine.execute(query) result = result.fetchall() points=[] base_points=[] for u in result: p = [float(u[0]),float(u[1])] points.append(p) for u in result2: p = [float(u[0]),float(u[1])] base_points.append(p) points = np.array(points) base_points = np.array(base_points) ``` のような感じで、本当の緯度経度を引数としているんのですが、こちらで回すと、 --------------------------------------------------------------------------- IndexError Traceback (most recent call last) <ipython-input-3-961842822e4d> in <module>() 102 mcovered = None 103 for i, bp in enumerate(base_points): --> 104 dist = vCAL_RHO(points, bp) 105 covered = dist < 50. 106 cnt = np.sum(covered) <ipython-input-3-961842822e4d> in vCAL_RHO(p1s, p2) 39 rad_A = np.radians(p1s) 40 rad_B = np.radians(p2) ---> 41 pA = np.arctan(rb/ra*np.tan(rad_A[:, 0])) 42 pB = np.arctan(rb/ra*np.tan(rad_B[0])) 43 xx = np.arccos(np.sin(pA)*np.sin(pB) + np.cos(pA)*np.cos(pB)*np.cos(rad_A[:, 1] - rad_B[1])) IndexError: index 0 is out of bounds for axis 1 with size 0 というようなエラーになってしまいます。 原因等わかりますでしょうか?
mkgrei

2018/06/14 03:18

クエリの返り値がないときに、pointsがnp.array([[]])のときではないでしょうか。
yositigu

2018/06/14 03:27

ありがとうございます。具体的な対処法を教えていただけないでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問