0. 준비하기
- 필요한 라이브러리를 설치해주고, 각 버스정류장 좌표 / 각 상권 중앙 좌표 / 지하철 역 좌표 데이터를 불러와주자.
1. 좌표계 변환하기
- 이번 반경 내 좌표 찾기에서 기준 좌표가 되는 상권 중앙 좌표값을 다른 좌표들과 함께 맞춰주고 직관적으로 이해하기 쉽게 WGS84 위경도 좌표로 변환해주자
# 좌표 변환 함수 정의
def transform_coordinates(x, y):
epsg5181 = pyproj.CRS("EPSG:5181")
wgs84 = pyproj.CRS("EPSG:4326")
transformer = pyproj.Transformer.from_crs(epsg5181, wgs84, always_xy=True)
longitude, latitude = transformer.transform(x, y)
return f"{latitude}, {longitude}"
# 좌표 변환 적용하여 상권 중앙위경도 값 추가
df_all['상권_중앙위경도_값'] = df_all.apply(lambda row: transform_coordinates(row['엑스좌표_값'], row['와이좌표_값']), axis=1)
2. 좌표 컬럼 만들기
- 버스, 지하철 좌표 값들도 위경도 좌표로 만들어 칼럼을 새로 만들어주자.
- 여기서 주목해야할 것은 중복값을 제거하는 것이다. 이유는 현재 데이터는 버스데이터의 경우 3개년 각 분기별 총 12개, 그러니까 같은 버스 정류장의 데이터가 한 점의 좌표를 가지자면 총 12개가 겹쳐있어 개수 세기에 혼란을 불러일으키기 때문이다. 이는 지하철 데이터도 마찬가지이다.
# '버스정류장_위경도_값' 열 생성
BUS_GN['버스정류장_위경도_값'] = BUS_GN['Y좌표'].astype(str) + ', ' + BUS_GN['X좌표'].astype(str)
BUS = BUS_GN[['버스정류장ARS번호', '버스정류장_위경도_값']].drop_duplicates().reset_index(drop=True)
# '지하철역_위경도_값' 열 생성
SUB_GN['지하철역_위경도_값'] = SUB_GN['위도'].astype(str) + ', ' + SUB_GN['경도'].astype(str)
SUB = SUB_GN[['지하철역', '지하철역_위경도_값']].drop_duplicates().reset_index(drop=True)
3. 반경 내 좌표 개수 세기
- 반경 300미터 내에 버스 정류장 수를 다음의 코드를 이용하여 구하고, 칼럼으로서 나타낼 수 있다.
- within_radius(coord1, coord2)
이 함수는 두 지점 간의 거리를 계산하고, 그 거리가 300 미터 이내에 있는지 여부를 판단합니다. coord1과 coord2는 좌표를 나타내며, geodesic 함수를 사용하여 두 지점 사이의 거리를 계산합니다. 만약 거리가 300 미터 이내이면 True를 반환하고, 그렇지 않으면 False를 반환합니다.
- count_bus_stops_within_radius(all_coords, bus_coords)
이 함수는 상권 중앙 좌표를 기준으로 반경 내에 있는 버스 정류장의 수를 계산합니다. all_coords는 모든 상권 중앙 좌표의 리스트이고, bus_coords는 버스 정류장들의 좌표를 나타내는 리스트입니다. 이 함수는 bus_coords의 각 정류장에 대해, all_coords 중 어떤 좌표와의 거리가 300 미터 이내에 있는지 확인하고, 맞다면 count를 증가시킵니다.
최종적으로는 반경 내에 있는 버스 정류장의 총 수를 반환합니다.
from geopy.distance import geodesic
# 좌표 간 거리를 계산하고, 300미터 이내에 있는지 확인하는 함수
def within_radius(coord1, coord2):
return geodesic(coord1, coord2).meters <= 300
# 상권 중앙 좌표를 기준으로 반경 내에 있는 버스 정류장 수를 계산하는 함수
def count_bus_stops_within_radius(all_coords, bus_coords):
count = 0
for bus_coord in bus_coords:
if any(within_radius(all_coord, bus_coord) for all_coord in all_coords):
count += 1
return count
# ALL 데이터프레임의 좌표값을 추출하여 리스트로 변환
all_coords = [tuple(map(float, coord.split(', '))) for coord in ALL['상권_중앙위경도_값']]
# BUS 데이터프레임의 좌표값을 추출하여 리스트로 변환
bus_coords = [tuple(map(float, coord.split(', '))) for coord in BUS['버스정류장_위경도_값']]
# 각 상권의 중앙 좌표를 기준으로 반경 내에 있는 버스 정류장 수를 계산하여 컬럼에 추가
ALL['버스정류장_수'] = [count_bus_stops_within_radius([all_coord], bus_coords) for all_coord in all_coords]
- 비슷한 내용으로 지하철 역 개수까지 구해주면 다음과 같이 결과가 나오게 된다.
from geopy.distance import geodesic
# 좌표 간 거리를 계산하고, 300미터 이내에 있는지 확인하는 함수
def within_radius(coord1, coord2):
return geodesic(coord1, coord2).meters <= 300
# 상권 중앙 좌표를 기준으로 반경 내에 있는 지하철 역 수를 계산하는 함수
def count_subway_stations_within_radius(all_coords, subway_coords):
count = 0
for subway_coord in subway_coords:
if any(within_radius(all_coord, subway_coord) for all_coord in all_coords):
count += 1
return count
# ALL 데이터프레임의 좌표값을 추출하여 리스트로 변환
all_coords = [tuple(map(float, coord.split(', '))) for coord in ALL['상권_중앙위경도_값']]
# SUB 데이터프레임의 좌표값을 추출하여 리스트로 변환
subway_coords = [tuple(map(float, coord.split(', '))) for coord in SUB['지하철역_위경도_값']]
# 각 상권의 중앙 좌표를 기준으로 반경 내에 있는 지하철 역 수를 계산하여 컬럼에 추가
ALL['지하철역_수'] = [count_subway_stations_within_radius([all_coord], subway_coords) for all_coord in all_coords]
ALL
********** 참 고 용 데 이 터 프 레 임 **********
'프로젝트 > (세미)강남구 지역 상권 기반 시간대별 편의점 매출 예측' 카테고리의 다른 글
6. 프로젝트 회의 정리(09.11, 주말 포함) (0) | 2023.09.11 |
---|---|
좌표 데이터(.shp) -4 영역 내 좌표 개수 세기 / 해당 좌표 출력하기 (0) | 2023.09.10 |
5. 프로젝트 회의 정리(09.08) (0) | 2023.09.08 |
4. 프로젝트 회의 정리(09.07) (0) | 2023.09.07 |
좌표 데이터(.shp) -2 폴리곤 좌표 데이터를 파이썬에서 활용하는 방법 (0) | 2023.09.07 |