1. 이제 지금까지 만들어온 데이터를 시각화할 차례다. 우선 데이터를 다시 불러와준다.
import pandas as pd
df = pd.read_csv('../data/03. best_sandwiches_list_chicago_ds_study02.csv')
2. 지도 시각화를 위한 라이브러리들을 불러와준다.
import folium
import googlemaps
import numpy as np
from tqdm import tqdm
3. 먼저 googlemaps로 주소들을 검색하여 좌표(lat, lng)를 표시해준다.
gmaps_key = 'API키 여기에'
gmaps = googlemaps.Client(key=gmaps_key)
lat = []
lng = []
for idx, row in tqdm(df.iterrows()):
if not row['Access'] == 'Multiple location':
target_name = row['Access'] + ', ' + 'Chicago'
gmaps_output = gmaps.geocode(target_name)
location_output = gmaps_output[0].get('geometry')
lat.append(location_output['location']['lat'])
lng.append(location_output['location']['lng'])
else:
lat.append(np.nan)
lng.append(np.nan)
*** 여기서 오류 발생! ***
gmaps_output이 존재하지 않아 아무 값도 들어가지 않는 경우가 생겼다.
해당 경우를 발견할 경우 target_name을 반환하도록 코드를 다시 짰다.
lat = []
lng = []
for idx, row in tqdm(df.iterrows()):
if not row['Address'] == 'Multiple location':
target_name = row['Address'] + ', ' + 'Chicago'
gmaps_output = gmaps.geocode(target_name)
if gmaps_output: # 결과가 있는 경우에만 처리
location_output = gmaps_output[0].get('geometry')
lat.append(location_output['location']['lat'])
lng.append(location_output['location']['lng'])
else:
# 결과가 없는 경우에 대한 처리
lat.append(np.nan)
lng.append(np.nan)
print("No geocode results found for:", target_name)
else:
lat.append(np.nan)
lng.append(np.nan)
이런 결과가 표시됐다.
34it [00:04, 7.86it/s]
No geocode results found for: 15 N. Milwaukee Ave., Chicago
50it [00:07, 6.85it/s]
찾아보니 15 N. Milwaukee Ave., Chicago는 정말로 존재하지 않는다. 페이지에 직접 가서 확인해보니 주소가 다르다는 걸 발견했다.
33. Paramount Room Paramount Reuben
Briny lean brisket, kraut, and melted Gruyère neatly packaged between two thick slices of toasted marble rye
www.chicagomag.com
페이지를 들어가보면 해당 부분이 $13. 415 N. Milwaukee Ave., 312-829-6300, ...으로 표시되어 있다.
즉 앞부분의 '4'가 잘못 잘린 것이다. 왜 그럴까? 정규표현식을 다시 확인해봤다.
tmp_split = ['', '$6. Multiple location', ' dawalikitchen.com']
tmp_string = re.search('\$\d+\.(\d+)?', tmp_split[1]).group()
tmp_split[1][len(tmp_string)+2:]
# 'ultiple location'
'\$\d+\.(\d+)?'라는 정규표현식은 $ + 숫자(하나 이상) + . + 숫자(하나 이상, 있어도 되고 없어도 됨)인 str을 찾는 것이다. 그런데 이상하게도 저렇게 하면 $6. 뒤의 공백문자와 M(' M)을 잘라버린다. 이번엔 다른 방식으로 정규표현식을 수정해보았다.
tmp_string = re.search('\$\d+(\.\d+)?', tmp_split[1]).group()
tmp_split[1][len(tmp_string)+2:]
# 'Multiple location'
$ + 숫자(하나 이상) + (온점(' . ' ) + 숫자(하나 이상, 있어도 되고 없어도 됨)) 이란 식으로 묶어 주었다. 그러니 제대로 표시된다.
수정된 코드로 다시 bs4를 돌려 dataframe을 다시 만들어주었다.
lat = []
lng = []
for idx, row in tqdm(df.iterrows()):
if not row['Address'] == 'Multiple locations':
target_name = row['Address'] + ', ' + 'Chicago'
gmaps_output = gmaps.geocode(target_name)
if gmaps_output: # 결과가 있는 경우에만 처리
location_output = gmaps_output[0].get('geometry')
lat.append(location_output['location']['lat'])
lng.append(location_output['location']['lng'])
else:
# 결과가 없는 경우에 대한 처리
lat.append(np.nan)
lng.append(np.nan)
print("No geocode results found for:", target_name)
else:
lat.append(np.nan)
lng.append(np.nan)

문제를 해결했다. 다시 시작!
*** 다시 지도 시각화 ***
4. lat과 lng라는 컬럼을 만들어준다.

5. 결과를 바탕으로 지도에 표시해본다. folium.Map을 이용한다.
mapping = folium.Map(location = [41.8781136, -87.6297982], zoom_start = 11)
for idx, row in df.iterrows():
if not row['Address'] == 'Multiple locations':
folium.Marker([row['lat'], row['lng']], popup = row['Cafe']).add_to(mapping)
mapping

6. 기존에 배웠던 부분을 바탕으로 툴팁, 아이콘을 더 표시해보자.
mapping = folium.Map(location = [41.8781136, -87.6297982], zoom_start = 11)
for idx, row in df.iterrows():
if not row['Address'] == 'Multiple locations':
folium.Marker([row['lat'], row['lng']], popup = row['Cafe'], tooltip=row['Menu'], icon = folium.Icon(
icon='coffee',
prefix = 'fa')
).add_to(mapping)
mapping

아이콘에 마우스를 올리면 메뉴가 나타나고, 아이콘을 클릭하면 카페 이름이 표시된다.
'데이터분석 > 미니프로젝트 02. 웹 데이터 분석(크롤링)' 카테고리의 다른 글
| 미니프로젝트 02-01-03. 시카고 맛집 데이터 하위 페이지 분석 (2) | 2024.04.13 |
|---|---|
| 미니프로젝트 02-01-02. 위키백과 문서 정보 가져오기, 시카고 맛집 메인페이지 분석 (0) | 2024.04.12 |
| 미니프로젝트 02-01-01. Beatiful Soup 기초와 웹데이터 (1) | 2024.04.05 |