지난 글에서 서울특별시 공중화장실 공중데이터를 판다스 데이터프레임으로 만들고 간단히 정제작업을 해 보았는데요. 정제한 데이터프레임을 가지고 태블로를 이용해서 아주 간단히만 시각화 작업을 진행해 보았습니다.

 

 

 

대시보드 구성 방법

  1. 서울시의 25개 구별 공중화장실 수 합계를 계산하여 그 수를 비교할 수 있도록 시각화했습니다.
  2. 대시보드의 왼쪽에는 지도를 배치하여 화장실의 수를 원의 크기와 색깔로 직관적으로 파악할 수 있도록 구성했습니다
    • 지도를 확대하면 보이지 않는 레이블을 모두 확인할 수 있어요.
    • 화장실 수가 많을수록 원의 크기가 큽니다.
    • 화장실 수가 많을수록 원의 색깔이 진합니다.
  3. 대시보드의 오른쪽에는 가로막대그래프를 배치하여 수치별로 좀더 직관적인 비교가 가능하도록 구성했습니다.
    • 오른쪽의 비교 파라미터를 이용해서 비교선을 100단위로 조절하면서 이동시킬 수 있어요.
    • 비교선을 움직이면서 비교선을 기준으로 색깔이 바뀌는 것을 확인할 수 있어요.

 

태블로 퍼블릭으로 보러가기 (클릭)

 

지하철

지하철

public.tableau.com

클릭하시면 태블로 퍼블릭 웹사이트에서 인터렉티브하게 직접 결과를 조절해 보실 수 있습니다.

 


 

 

<시각화 이후 생각해볼만한 것들>

 

1. 구별 화장실 수와 구별 면적의 관계는 어떻게 되는가?
2. 구별 화장실 수와 지하철 역의 개수의 상관관계가 있는가?
3. 구별 화장실 수와 구별 인구 수의 관계는 어떻게 되는가? 인구와 구별 화장실 총 수는 비례하는가?
4. 서울특별시 구별 장애인 화장실 데이터를 따로 구할 수 있는가? 구할 수 있다면, 전체 화장실과 장애인 화장실의 비율을 비교해 보자.
5. 상업 단지와 화장실 수의 상관관계가 있는가?

6. 관광 구역과 화장실 수의 상관관계가 있는가?

7. 공공화장실 중에서 지하철 역 화장실의 개수를 특정할 수 있는가? 있다면 그 비율은 어떻게 되는가?

8. 지하철 역 화장실 개수를 구할 수 있다면, 지하철 노선별 유동인구 데이터와 병합하여 화장실의 갯수가 적절하게 비치되어 있는지 비교해보자.

 

 

 

여기까지입니다 :-) 좀더 생각해볼 수 있을것 같지만 본격적인 개인 EDA 프로젝트 준비를 위해서 이번엔 이정도로 간단히만 포스팅을 마치려고 합니다. 쉽고 짧은 작업이었지만 맘에드는 공공데이터를 구하고, 정제하고, 시각화 후 생각해볼거리 도출까지 은근 시간이 걸렸네요. 다음엔 더 능숙하고 멋진 프로젝트를 가져와서 공유해보겠습니다. 감사합니다. :)

 

 


 

 

(+) 판다스 데이터프레임 CSV파일로 내보내기 한 후 태블로에 불러온 과정

 

t.to_csv("toilet_df.csv")

 

먼저 to_csv() 메소드를 통해 간단하게 csv파일로 내보내기를 해주었습니다. 저는 구글 코랩에서 실습을 진행했습니다.

 

 

 

 

 

구글 코랩의 왼쪽 파일메뉴에서 간단하게 바로 다운로드를 해서 다운로드 폴더에 넣어 주었는데요. 로컬 환경에 따로 다운로드하지않고 태블로 퍼블릭 환경에서 구글 드라이브를 연동해서 바로 오픈해도 됩니다.

 

 

 

 

 

태블로 퍼블릭 프로그램을 실행하고 로컬 환경에 다운로드한 toilet_df.csv 파일을 오픈했습니다.

 

 

 

따로 사용하지 않을 예정인 산지, 부지번 컬럼은 숨기기(Hide) 해주었습니다. 이후 시트 2개에서 작업을 하고 대시보드 1개에서 두개를 합쳐주는 방식으로 간단히 끝을 내주었습니다.

 

 

 

 
서울시 공중화장실 공공데이터를 가지고 아주 간단한 데이터 시각화, 분석 실습을 해 보려고 합니다.
먼저 이번 포스팅에는 파이썬 pandas 라이브러리를 이용해서 데이터 전처리 작업한 것을 간단히 정리해 보았습니다. 
데이터 시각화, 분석은 태블로 프로그램을 이용하여 마친 뒤 다음 포스팅에 이어서 올리도록 하겠습니다.
 
 
https://data.seoul.go.kr/dataList/OA-1370/S/1/datasetView.do

열린데이터광장 메인

데이터분류,데이터검색,데이터활용

data.seoul.go.kr

 
사용한 데이터 링크입니다.
 


 

1. pandas : 필요없는 컬럼 삭제, 인덱스 지정

import pandas as pd

t = pd.read_csv("toilet.csv", engine='python', encoding = "cp949")
t

 
pd.read_csv를 이용해서 데이터를 불러오는데 한글 깨짐이 좀 있어서 encoding = "cp949"를 이용해주니 깔끔하게 불러오기가 잘 되었습니다.

 
먼저 value_counst()를 이용해서 대략적으로 확인해보니 별 다른 정보가 담겨있지 않은 관계로 새주소명, 생성일 컬럼은 삭제하기로 결정했습니다. 또, 고유번호에 중복값이 없는것을 확인한 관계로 고유번호를 인덱스로 지정해주겠습니다.

# 새주소명, 생성일 컬럼 드랍(삭제)
t = t.drop('새주소명', axis=1)
t.drop('생성일', axis = 1, inplace = True)

# 고유번호 컬럼 중복값 없는지 확인
len(t['고유번호'].unique()) == len(t['고유번호'])  # True

# 고유번호 인덱스화
t.set_index('고유번호', inplace = True)

 
필요없는 컬럼을 삭제하고 인덱스를 고유번호로 바꾸어 주니 어느정도 보는 게 깔끔해졌습니다.
이제 구명과 법정동명을 확인해보려고 하는데요.
 
 

2. 구명

t['구명'].value_counts()

 
value_counts()를 이용해서 확인해 보니

  1. 끝에 '구'가 붙어 있지 않은 구
  2. 오타 작렬한 구
  3. 빌딩이 왜 여기서 나와? 갈암구는 또 어디야? 갈현송방차풀소는 뭐야?

이것들을 해결해줘야 할 것 같습니다.
먼저 구가 안붙어있는 것들에 구를 붙여줘 보기로 했습니다. (예:노원 > 노원구)

t['구명'] = t['구명'].apply(lambda x: x + '구' 
                          if x in ['동작', '금천', '강서', '양천', '노원', '관악', '영등포', '서대문'] 
                          else x)

 
'구명'이 동작/금천/강서/양천/노원/관악/영등포/서대문 중 하나인 경우
컬럼에 apply와 lambda 함수를 이용해서 끝에 '구'를 붙여 줬습니다. 해당사항이 없는 경우는 그냥 놔두도록 처리했습니다.

t['구명'].value_counts()


그 외 갈현송방차풀소~남서울빌딩에 해당하는 row들은 그냥 제거하겠습니다.

# 이것들에 해당하는 '구명'을 가진 row들을 제외한(~) 줄만 남겨서 t에 재할당
t = t[~t['구명'].isin(['갈현송방차풀소', '송북구', '송파ㅜ', '영등로구', 
                      '영등표구', '송파두성빌딩', '갈암구', '구로수', '남서울빌딩'])]
len(t['구명'].value_counts().index)
# 25

 
혹시 몰라 확인해 보니 총 25개의 구가 있는것이 잘 확인되었습니다. 검색해보니 서울에는 25개 자치구와 426개 행정동이 있다고 하네요! 서울 살면서도 계속 까먹어요... 상식으로 외워둬야지.
 
법정동은 426개를 일일이 확인하기 불가능 + 의미가 없는 것 같아서 일단 놔두도록 하겠습니다. 다음 포스팅에는 태블로를 이용하여 간단한 시각화를 해서 가져오도록 하겠습니다!
 

 

 

 

FutureWarning: use_inf_as_na option is deprecated and will be removed in a future version. Convert inf values to NaN before operating instead. with pd.option_context('mode.use_inf_as_na', True): 

 

주피터 노트북이나 코랩에서 pandas, seaborn, matplotlib 등 라이브러리를 사용할 때 위와 같이 퓨처 워닝 어쩌구 하면서 경고 메세지가 나타나서 꼴보기 싫은 경우가 있습니다.

 

이럴 때 warning 라이브러리를 임포트하는 방식으로 간단하게 해결이 가능합니다.

 

import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)

 

before

 

after

 

 

 

+ Recent posts