working_helen
[데이터 수집] 위도/경도 기반 지도 반경 내 데이터 본문
데이터 수집 단계에서 학습한 내용 중 세번째로 위경도 기반 지도상 반경 내 데이터를 수집하는 방법에 대해 공부해본다.
1. Haversine 하버사인 공식이란?
2. Haversine 하버사인 공식 코드
1. Haversine 하버사인 공식이란?
- 구면에서 두 점 사이의 최단 거리 구할 때 쓰이는 공식
- 평면에서 두 지점을 이은 직선이 최단거리인 반면, 구면에선 곡률의 영향으로 인해 단순히 두 지점을 직선 경로가 최단거리가 되지 않는다. 원의 일부, 즉 호 모양의 경로가 최단거리가 된다.
- 지도 상의 두 위치는 구형의 지구 위의 두 지점이므로 구면에서의 최단거리 공식을 통해 두 지점 간 거리를 구한다.
- 하버사인 공식은 두 지점의 위도, 경도, 지구 반지름을 이용해 두 지점 간 호의 길이를 계산한다.
2. Haversine 하버사인 코드
1) 공식 수식
(식 1) theta 구하기 : theta = hav역함수(h)
(식 2) 구한 theta로 두 점 사이 거리 d 구하기 (r은 지구 반지름)
2) 파이썬 코드
- 방법 1. Haversine 하버사인 공식을 이용하여 두 지점 간의 거리를 계산하는 함수 정의하기
import math
def haversine_1(lat1, lon1, lat2, lon2):
radius = 6371 # 지구의 반지름 (단위: km)
# 위도 및 경도를 라디안 단위로 변환
lat1, lon1, lat2, lon2 = map(math.radians, [lat1, lon1, lat2, lon2])
# 위도 및 경도 차이 계산
dlat = lat2 - lat1
dlon = lon2 - lon1
# Haversine 공식 적용
a = math.sin(dlat / 2) ** 2 + math.cos(lat1) * math.cos(lat2) * math.sin(dlon / 2) ** 2
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
distance = radius * c
# 두 지점 간의 거리 (단위: km)
return distance
def haversine_2(lat1, lon1, lat2, lon2):
radius = 6371 # 지구 반지름 (단위: km)
# 위도 및 경도 차이 계산 > 라디안 단위로 변환
toRadian = math.pi / 180
deltaLatitude = abs(lat1 - lat2) * toRadian
deltaLongitude = abs(lon1 - lon2) * toRadian
# Haversine 공식 적용
sinDeltaLat = math.sin(deltaLatitude / 2)
sinDeltaLng = math.sin(deltaLongitude / 2)
squareRoot = math.sqrt(sinDeltaLat * sinDeltaLat +
math.cos(x1 * toRadian) * math.cos(x2 * toRadian) * sinDeltaLng * sinDeltaLng)
distance = 2 * radius * math.asin(squareRoot);
# 두 지점 간의 거리 (단위: km)
return distance
- 방법 2. python haversine package 이용
unit` 조건을 변경하여 FEET, KILOMETERS, MILES 등의 단위로 리턴 가능
pip install haversine
from haversine import haversine
haversine((lat1, lon1), (lat2, lon2), unit = 'km')
Jupyter Notebook
import pandas as pd
import numpy as n
import math
반경 500m 내 인근 카페 수 개수 세기¶
방법 1. Haversine 하버사인 공식을 이용하여 두 지점 간의 거리를 계산하는 함수 정의하기
def haversine_1(lat1, lon1, lat2, lon2):
radius = 6371
lat1, lon1, lat2, lon2 = map(math.radians, [lat1, lon1, lat2, lon2])
dlat = lat2 - lat1
dlon = lon2 - lon1
a = math.sin(dlat / 2) ** 2 + math.cos(lat1) * math.cos(lat2) * math.sin(dlon / 2) ** 2
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
distance = radius * c
return distance
def haversine_2(x1,y1,x2,y2):
radius = 6371
toRadian = math.pi / 180
deltaLatitude = abs(x1 - x2) * toRadian
deltaLongitude = abs(y1 - y2) * toRadian
sinDeltaLat = math.sin(deltaLatitude / 2)
sinDeltaLng = math.sin(deltaLongitude / 2)
squareRoot = math.sqrt(sinDeltaLat * sinDeltaLat +
math.cos(x1 * toRadian) * math.cos(x2 * toRadian) * sinDeltaLng * sinDeltaLng)
distance = 2 * radius * math.asin(squareRoot);
return distance
방법 2. python haversine package 이용
#pip install haversine
from haversine import haversine
haversine((37.5118952, 126.8331574), (37.501861, 127.0949884), unit = 'km')
23.12274213413393
haversine_1(37.5118952, 126.8331574, 37.501861, 127.0949884)
23.12271019568632
haversine_2(37.5118952, 126.8331574, 37.501861, 127.0949884)
23.122710195686643
카페 = pd.read_csv(path+'/2단계 폐영업_크롤링_최종.csv')
카페 = 카페.iloc[:, 1:]
카페
상호명 | 시군구명 | 행정동명 | 도로명주소 | 위도 | 경도 | 폐업여부 | 소득분위 | 가구수 | 1년 생존율 | 3년 생존율 | 5년 생존율 | 최근 10년 기준 평균영업기간 | 최근 30년 기준 평균영업기간 | 임대시세 | 유동인구 | 주거인구 | 직장인구 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | (주)도피오커피서남병원인 | 양천구 | 신정3동 | 서울특별시 양천구 신정이펜1로 20(신정동, 서남병원) | 37.511895 | 126.833157 | y | 7 | 16957 | 75.0 | 75.0 | 25.0 | 2.8 | 3.3 | 167322.0 | 33003 | 164 | 27 |
1 | 커피나무 | 강남구 | 논현2동 | 서울특별시 강남구 언주로148길 14(논현동,2층) | 37.520407 | 127.036095 | y | 8 | 11676 | 72.3 | 29.8 | 21.3 | 2.6 | 3.9 | 166981.0 | 80595 | 150 | 383 |
2 | (주)프라빈 | 강남구 | 역삼1동 | 서울특별시 강남구 테헤란로22길 11(지상9층 역삼동) | 37.499232 | 127.035300 | y | 7 | 23983 | 67.6 | 42.6 | 33.3 | 2.7 | 4.0 | 182473.0 | 72621 | 152 | 724 |
3 | (주)올댓스토리 | 강남구 | 역삼1동 | 서울특별시 강남구 강남대로94길 67(지상5층 역삼동) | 37.500838 | 127.032530 | y | 7 | 23983 | 67.6 | 42.6 | 33.3 | 2.7 | 4.0 | 182473.0 | 72621 | 152 | 724 |
4 | (주)르샹스 | 송파구 | 삼전동 | 서울특별시 송파구 백제고분로32길 6-1(지상2층 삼전동) | 37.501861 | 127.094988 | y | 6 | 16326 | 62.5 | 31.3 | 12.5 | 2.5 | 3.2 | 173792.0 | 64867 | 317 | 78 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
20881 | 그녀의커피:카페드엘르 | 구로구 | 오류1동 | 서울특별시 구로구 고척로3길 7 | 37.495637 | 126.840154 | n | 6 | 11857 | 100.0 | 100.0 | 0.0 | 2.2 | 3.9 | 170402.0 | 45180 | 323 | 61 |
20882 | 타래커피 | 은평구 | 갈현1동 | 서울특별시 은평구 연서로29길 8 | 37.618955 | 126.919244 | n | 6 | 11052 | 80.0 | 60.0 | 40.0 | 2.4 | 3.4 | 137228.0 | 84587 | 252 | 29 |
20883 | 호두대장 | 양천구 | 신정1동 | 서울특별시 양천구 은행정로5길 30 | 37.521016 | 126.856447 | n | 9 | 7170 | 33.3 | 0.0 | 0.0 | 2.4 | 3.8 | 129084.0 | 39518 | 289 | 160 |
20884 | 더벤티 | 서초구 | 서초1동 | 서울특별시 서초구 서초중앙로22길 25 | 37.493461 | 127.015447 | n | 8 | 9350 | 60.0 | 30.0 | 20.0 | 2.5 | 3.8 | 149977.0 | 54635 | 152 | 343 |
20885 | 향과울림 | 노원구 | 상계1동 | 서울특별시 노원구 동일로230다길 63 | 37.674125 | 127.057966 | n | 7 | 15619 | 66.7 | 44.4 | 11.1 | 3.0 | 3.4 | 144872.0 | 12210 | 78 | 11 |
20886 rows × 18 columns
store_latitude = list(카페["위도"])
store_longitude = list(카페["경도"])
인근카페수 = list()
for i in range(20886):
row=카페.iloc[i]
latitude = row["위도"]
longitude = row["경도"]
count=0
for index in range(20886):
distance = haversine(latitude, longitude, store_latitude[index], store_longitude[index])
if 0 < distance and distance <= 0.5:
count+=1
#print(index, 카페.iloc[index]["상호명"])
인근카페수.append(count)
카페["인근 카페수"] = 인근카페수
인근카페수_df=카페.loc[:, ["상호명", "인근 카페수"]]
인근카페수_df
상호명 | 인근 카페수 | |
---|---|---|
0 | (주)도피오커피서남병원인 | 10 |
1 | 커피나무 | 79 |
2 | (주)프라빈 | 140 |
3 | (주)올댓스토리 | 167 |
4 | (주)르샹스 | 53 |
... | ... | ... |
20881 | 그녀의커피:카페드엘르 | 23 |
20882 | 타래커피 | 84 |
20883 | 호두대장 | 57 |
20884 | 더벤티 | 94 |
20885 | 향과울림 | 32 |
20886 rows × 2 columns
인근카페수_df.to_csv(path+"/인근카페수_df.csv")
Reference
https://en.wikipedia.org/wiki/Haversine_formula
https://velog.io/@revimal/Mathematics-Haversine-Formula
https://kayuse88.github.io/haversine/
https://stricky.tistory.com/284
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=haley2203&logNo=222308267667&categoryNo=43&proxyReferer=
'TAVE > 뿌스팅 project' 카테고리의 다른 글
[데이터 전처리] EDA 및 변수 선택 (0) | 2023.08.07 |
---|---|
[데이터 수집] 데이터 수집 Workflow (0) | 2023.08.07 |
[모델링] 불균형 데이터 처리/SMOTH (0) | 2023.08.01 |
[데이터 수집] selenium 웹데이터 크롤링 (0) | 2023.07.04 |
[데이터 수집] API의 개념 / XML 형태 처리 (0) | 2023.07.04 |