(220905) 와이파이 현황 분석 및 가장 가까운 와이파이 찾기 지도 시각화

이은경·2022년 9월 5일
0

1. 무료 와이파이 데이터 분석 및 차트 그리기


1) 무료 와이파이 데이터 전처리


import pandas as pd
import plotly. express as px
df = pd.read_csv('/content/dataset.csv', encoding ='EUC-KR')
  • 자료를 데이터 프레임 형태로 읽어오기
df.info()
  • 1) 데이터를 읽어오기 전에도 csv 파일을 노트패드로 열어서 데이터에 어떤 정보가 담겨있는지 어떤 분석을 할 수 있을지 인코딩은 어떤 형식인지 파악한다.
  • 2) df.info()를 통해 null값의 여부, 데이터 type을 확인할 수 있다.
df.isna() # Null값을 'True'로 처리해줌
df.isna().sum() # Null데이터가 몇 건인지 한번에 확인 가능
  • 1) 첫번째 코드는 모든 데이터 값의 null값 여부를 출력해주는데 null값인 경우 True로 표시된다.

  • 2) 두번째 코드는 컬럼별로 어떤 컬럼에 몇 개의 null값이 있는지 보여준다. 아래의 출력값을 보면 설치년월에 5천여개의 null값이 있는 것을 알 수 있다.

기준 컬럼별 갯수가 궁금해 카운트 하고 싶을 때는 두가지 방법이 있다. (집계함수)

  • 1) 단순히 값을 계산해서 보여주는 방법: 분석 전 또는 분석 후 누락값은 없는지 분석이 제대로 이루어지는지 예측 또는 점검할 때 사용 가능하다.
df['설치시도명'].value_counts()

  • 2) 기준이 된 컬럼을 인덱스로 설정 후 나머지 컬럼별로 값이 있는 행 갯수를 산출
df.groupby(['설치시도명']).count()

그럼 여러 컬럼을 이용해 groupby하면 어떨까?

group_df = df.groupby(by=['설치시도명','설치시설구분', '서비스제공사명']).count() 
group_df
  • 위 세 컬럼이 인덱스이자 기준이 되며 나머지 컬럼별로 값이 있는 데이터 갯수를 출력한다. 병합된 셀로 차트를 그릴 수 없다.(컬럼별로 값이 다름)
group_df = df.groupby(by=['설치시도명','설치시설구분', '서비스제공사명']).size() 
group_df
  • 위 세 컬럼이 인덱스이자 기준이 되며 세 기준을 모두 충족하는 중복되는 갯수를 no name으로 출력한다. 이 데이터는 시리즈 형식이며 병합된 셀이 있어 차트를 그릴 수 없는 형식이다. 하지만 df형태로 변환시켜준다면 차트를 그릴 수 있다.

group_df = df.groupby(by=['설치시도명','설치시설구분', '서비스제공사명']).size().
reset_index(name='설치개수') 
group_df
  • 1) 리셋인덱스를 이용함으로써 df형식으로 만들고 이름을 '설치개수'로 만들어준다.
  • 2) 리셋인덱스는 그룹바이 전 각자의 인덱스를 초기화하고 새로이 인덱스 값을 넣어준다. 초기화 하지 않는다면 위 셀처럼 중복값은 병합되어 각각의 row가 온전하지 않게 된다.

참고. 데이터값 전처리

df.설치시설구분.unique()
df.loc[df.설치시설구분.str.contains('서민'), '설치시설구분'] = '서민복지시설'

  • 위와 같이 특정 컬럼의 데이터 값을 출력해 같은 값이나 특수기호로 인해 다른 값으로 분류된 값들을 한 형식으로 통일시켜준다.

2) 무료 와이파이 차트 그리기


# 설치시도별 WIFI 설치 현황
px.bar(group_df, x='설치시도명', y='설치개수')

  • 위 차트는 특정 시도 내에서 설치시설구분과 서비스제공사명이 일치하는 항목별로 묶인 데이터를 각각 나열한 차트이기 때문에 그래프 사이사이 흰 줄이 보인다.
# 설치시도별 WIFI 설치 현황
px.histogram(group_df, x='설치시도명', y='설치개수') #하나의 막대그래프로 작성

  • 이렇게 히스토그램을 이용하면 하나의 네모 박스인 sum값으로 차트를 그릴 수 있다.
# 설치시도별 WIFI 설치 현황
fig = px.pie(group_df, names ='설치시도명', values='설치개수')  
#figure를 사용해야 legend를 차트에 넣을 코드를 넣을 수 있다.
fig.update_traces(textposition = 'inside', textinfo = 'percent+label')
fig.show()

  • 파이차트를 그릴 때는 x, y 대신 legend이자 항목이 될 names 값과 그 수치인 values를 입력해야 한다. 'fig='없이도 차트를 그릴 수는 있지만 데이터를 차트 내부에 넣는 등 기타 서식을 위해서는 figure를 사용해야 한다.

3) 대전지역 무료 와이파이 차트 그리기


dj_df = df.loc[df['설치시도명']=='대전광역시']
  • 대전지역만 포함하는 데이터 프레임을 새로 만든다.
group_dj = dj_df.groupby(by=['설치년월','설치시군구명','설치시설구분', '서비스제공사명',
                        '관리기관명']).size().reset_index(name='설치개수')
group_dj
  • 위와 같이 집계 데이터 프레임 만들 때, 기준이 될 수 있는 컬럼을 모두 한 번에 groupby하여 유의미한 데이터 프레임을 만든다.

#시군구별 wifi 설치시설 구분 
fig = px.histogram(group_dj, x='설치시군구명', color ='설치시설구분') 
fig.show()

  • 이 차트는 아래 차트와 데이터가 다르다. 이 차트에서 y축은 그룹화된 시설 종류 수이다. 즉, 중구에는 설치시설구분이 기타이고 서비스제공사가 kt인 경우와 설치시설구분이 지역문화시설이고 서비스제공사가 kt인 경우 총 2가지 뿐이다.
#시군구별 wifi 설치개수와 설치시설 구분

fig = px.histogram(group_dj, x='설치시군구명', y='설치개수', color ='설치시설구분')
fig.show()

  • 여기서 y축은 와이파이의 설치개수이다. 중구에는 설치시설구분이 기타이고 서비스제공사가 kt인 경우가 3개, 설치시설구분이 지역문화시설이고 서비스제공사가 kt인 경우 2개 총 5개 뿐이다.

2. 나와 가장 가까운 와이파이 찾기


# 1. 라이브러리 임포트
import pandas as pd
import folium 
from geopy.geocoders import Nominatim
from geopy.distance import geodesic

# 2.데이터 준비하기
df = pd.read_csv('/content/dataset.csv', encoding = 'EUC-KR')

# 2-1. 대전 지역 데이터 준비하기
dj_df = df.loc[df['설치시도명']=='대전광역시']
  • 종전의 전처리된 데이터가 아닌 원시데이터에서 대전광역시에 설치된 와이파이만 포함하는 데이터 프레임을 새로 만든다.
# 3. 주소를 좌표로 변환할 함수 준비
def geocoding(address):
    geolocoder = Nominatim(user_agent = 'South Korea', timeout=None)
    geo = geolocoder.geocode(address)
    crd = {"lat": float(geo.latitude), "lng": float(geo.longitude)}
    return crd

# 4. 사용자에게 주소 입력받기
address = input('도로명주소를 입력하세요.')

# 5. 사용자 주소를 좌표로 변환 후, 튜플 형태로 변수에 담기
crd = geocoding(address)
IMHERE = (crd['lat'], crd['lng'])
  • 사용자가 도로명 주소를 입력하면 위도와 경도로 이루어진 좌표값으로 변환해주는 함수이다.
  • geopy는 튜플 형태로 데이터를 사용한다.
# 6. 데이터프레임 새로 생성 후, 사용자 주소와의 거리 계산하여 담기
c_wifi = pd.DataFrame(columns=['설치시군구명', '설치시설구분', '위도', '경도', '거리']) 

 for n in df.index:
   w_loc = (df.loc[n, '위도'], df.loc[n, '경도']) 
   c_wifi.loc[n] = [df.loc[n, '설치시군구명'], df.loc[n, '설치시설구분'],
                    df.loc[n, '위도'], df.loc[n, '경도'], geodesic(IMHERE,
                    w_loc).kilometers]

# 6-1. 대전 데이터프레임 새로 생성 후, 사용자 주소와의 거리 계산하여 담기
c_wifi = pd.DataFrame(columns=['설치시군구명', '설치시설구분', '위도', '경도', '거리']) 

for n in dj_df.index:
  w_loc = (dj_df.loc[n, '위도'], dj_df.loc[n, '경도']) 
  c_wifi.loc[n] = [dj_df.loc[n, '설치시군구명'], 
                   dj_df.loc[n, '설치시설구분'], dj_df.loc[n, '위도'], 
                   dj_df.loc[n, '경도'], geodesic(IMHERE, w_loc).kilometers]
  • 1) 사용자가 입력한 주소와 가까운 와이파이 데이터를 추출해 담기 위해 새로운 데이터 프레임을 만든다. 위와 같이 컬럼명을 지정하고 기존의 대전 데이터 프레임에서 컬럼명이 일치하는 데이터를 가져와 담을 수 있다.
  • 2) 대전 데이터프레임의 인덱스 수만큼 for문을 반복해 각 와이파이의 좌표(w_loc)와 입력값(IMHERE)의 차이를 계산해주는 함수를 사용해 거리를 계산하여 데이터 프레임에 담는다.
  • 3) 6번은 대전 지역으로 한정하지 않을 경우 데이터프레임을 선언하는 코드

# 7. 사용자 주소와 가장 가까운 무료 와이파이 상위 10곳 구하기
c_wifi = c_wifi.sort_values(by=['거리']).head(10)

# 8. 지도 준비
w_map = folium.Map(location=[df['위도'].mean(), df['경도'].mean()], zoom_start=14)

# 9. 사용자 주소와 상위 10곳의 와이파이 마커 올리기
folium.Marker([crd['lat'], crd['lng']], 
icon=folium.Icon(color='red', icon='glyphicon glyphicon-home')).add_to(w_map)

for n in c_wifi.index:
  folium.Marker([c_wifi.loc[n, '위도'], c_wifi.loc[n, '경도']],
                 popup='<pre>'+'시군구명: '+
                 c_wifi.loc[n, '설치시군구명']+', 시설구분: '+c_wifi.loc[n, '설치시설구분']+
                 '</pre>', icon=folium.Icon(color='cadetblue',icon='wifi'
                 ,prefix='fa')).add_to(w_map)

w_map
  • 1) 입력값과의 거리를 포함한 데이터 프레임을 거리 순으로 정렬해 상위 10곳을 다시 담기
  • 2) 지도는 전국 무료 와이파이 위치의 평균 위치를 찾아 설정
  • 3) 입력값을 먼저 지도 위에 시각화하고 for문을 돌면서 10개의 와이파이 정보를 담은 c_wifi를 시각화한다.


위 지도는 전국 와이파이 데이터 기준으로 시각화한 지도이다.

0개의 댓글