.. Cover Letter

ㅇ 프로젝트/TEAM_서울시 교통 인프라 분석

4. (EDA_프로젝트) 서울시 지하철 데이터로 지하철 노선도를 그려보자.

BrainKimDu 2022. 11. 14. 06:22

왜 해가 뜨고 있지

정말 쉽게 끝날줄 알았다.

근데 여기에서 4시간이 흘렸다.

새벽 6시.ㅋㅋ
내일은 지각이 확정이다.

빨리 자고 싶은데, 글안쓰면 잠이 안올거 같아서 글씀

프로젝트랑은 전혀 상관이 없는데

3에서 구한 지하철 위치 좌표로 지하철 노선도를 그려볼까?

이생각이 들었음.

내가 미쳤지

import pandas as pd
import folium



가공했던 데이터를 불러와서 보기 편하게 수정함

location = pd.read_csv('./metro_2022_10_location.csv', encoding='EUC-KR')
location = location.drop(['사용월',  '출근시간(04~09) 승차', '출근시간(07~10) 하차', '퇴근시간(16~20) 승차', '퇴근시간(17~21) 하차'
                         , '점심시간', '저녁시간', '늦은시간퇴근(20~02) 승차', '총 승차 인원',  '총 하차 인원', '월', '연도'], axis=1)
location.rename(columns={location.columns[0]: "0"}, inplace=True)
location = location.drop(['0'], axis=1)
location



list_df = pd.DataFrame(df['호선명'].value_counts())
list_df = list_df.reset_index()
list_df_list = list_df['index'].to_list()
list_df_list

호선별 리스트를 하나 작성했음.

sub_list = []
for i in list_df_list:
    sub_list.append(location[location['호선명'].isin([i])])
sub_list[0]


그래서 호선별로 분리해서 데이터프레임으로 만들어버림

for i in range(22):
    sub_list[i] = sub_list[i].reset_index()
    sub_list[i] = sub_list[i].reset_index()
sub_list[0]


인덱스 리셋해주고

color_list = ['red', 'blue', 'green', 'purple', 'orange', 'darkred', 'lightred', 'gray' ,'beige', 'darkblue', 'darkgreen', 'cadetblue', 
 'darkpurple', 'white', 'lightred', 'pink' ,'lightblue', 'lightgreen', 'gray', 'black', 'lightgray', 'darkred']
len(color_list)


# lightred 안됨
# skyblue


폴리움에서 사용가능한 모든 색깔이라고함. 더 있을거 같긴한데
나중에 RGB로 가능한지 알아보고 RGB로 되면 진짜 지하철 노선도처럼 만들어봐야지

my_map = folium.Map(location=[37.5502, 126.982], zoom_start=11, title="Stamen Toner")

for each in range(len(sub_list)):
    for i in range(len(sub_list[each])):
        if  (i+1) != len(sub_list[each]):
            start =  sub_list[each]['lat'][i], sub_list[each]['lng'][i] 
            end = sub_list[each]['lat'][i+1], sub_list[each]['lng'][i+1]
            
            location_data = [start, end]
            folium.PolyLine(locations=location_data, tooltip='Polyline', color=color_list[each]).add_to(my_map)

이자료를 바로 폴리움에 올리면 끝난다.
(폴리움은 직선을 만들게 설정)


???

뭐지?

아.. 지하철노선도 순서대로 표시를 정렬을 해줘야한다.

이때부터 머리가 터지기 시작했다.

진짜 그려보고 싶은데, 어캐해야할지..


그래서 알고리즘을 조금 고민했는데

거리의 최솟값을 계산하고
최솟값으로 이동을 하면서

A에서 시작하고
-> 끝까지 이동하면

다시 A로 돌아와서
<- 끝까지 이동하면 되지 않을까?


결론적으로 성공이였음.
(코테푸는기분..)

from haversine import haversine

위도 경도로 거리계산해주는 모듈

sub_list_sort = []
for i in list_df_list:
    sub_list_sort.append(sub_list[0][sub_list[0]['level_0'].isin([999999])])
sub_list_sort[0]

 


빈 데이터프레임 하나 만들어줌. (여기다가 차곡차곡쌓을거임)

그리고 대망의 알고리즘

for i in range(len(sub_list)):
    su = 0
    su_list = []
    su_list.append(0)
    count = 0

    sel = 1

    while True:
        list_temp = []
        start =  [sub_list[i]['lat'][su], sub_list[i]['lng'][su]]
        for j in range(len(sub_list[i])):
            if not(j in su_list):
                end =  [sub_list[i]['lat'][j], sub_list[i]['lng'][j]]
                a = haversine(start, end, unit = 'km')
                list_temp.append(a)
            else:
                list_temp.append(10)
        

        if min(list_temp) > 3:
            su = 0
            sel = 0
            count = count + 1 
            # 까치산 처럼 갈라지는 곳은 대응못함

        else:
            tmp = min(list_temp)
            index = list_temp.index(tmp)

            if sel == 1:
                sub_list_temp = sub_list[i][sub_list[i]['level_0'].isin([index])]
                sub_list_sort[i] = pd.concat([sub_list_sort[i] , sub_list_temp])

            elif sel == 0:
                sub_list_temp = sub_list[i][sub_list[i]['level_0'].isin([index])]
                sub_list_sort[i] = pd.concat([ sub_list_temp, sub_list_sort[i]])

            su_list.append(index)
            su = index
            
        if count == 2:
            break

        if len(su_list) == len(sub_list[i]):
            break

설명하면
위치정보 가져와서
거리계산하고 최솟값을 따라 아까 만든 데이터프레임에 행을 늘려나감

그 후 다음에 돌때
리스트에 없는 역만 골라서 거리 계산하고 최솟값 구하고 행을 늘려나감

그리고 끝에 도달하면 어렵게 생각했는데

이게 그 백트레킹 기법인가 그거 써야하는건가 생각했는데
진짜 간단한 아이디어로 풀림
최솟값이 비정상적인 거리의 값이면?

처음으로 돌아가라.


근데 지금 생각해보니 첫행이 끝쪽 주변에 있다면 불가능한 알고리즘이네
그거 포함해서
이 알고리즘의 최대 단점은 2호선의 순환선을 못돌아버림
분기되는 호선이 있다면 대응을 못함

for i in range(22):
    sub_list_sort[i] = sub_list_sort[i].drop(['level_0', 'index'], axis=1)
    sub_list_sort[i] = sub_list_sort[i].reset_index()
    sub_list_sort[i] = sub_list_sort[i].reset_index()
sub_list_sort[0]

대충 인덱스 맞춰주고

대충?? 순서대로 맞춰진 5호선

my_map = folium.Map(location=[37.5502, 126.982], zoom_start=11, title="Stamen Toner")

for each in range(len(sub_list_sort)):
    for i in range(len(sub_list_sort[each])):
        if  (i+1) != len(sub_list_sort[each]):
            start =  sub_list_sort[each]['lat'][i], sub_list_sort[each]['lng'][i] 
            end = sub_list_sort[each]['lat'][i+1], sub_list_sort[each]['lng'][i+1]
            
            
            location_data = [start, end]
            folium.PolyLine(locations=location_data, tooltip='Polyline', color=color_list[each]).add_to(my_map)


두근두근

my_map

 


뭔가 2프로 부족하지만 결국 완성해냈다.

내가 이겼나?