본문으로 바로가기

데이터 과학이라고 거창하게 부르지 않아도 요즘은 데이터를 이용해서 실제 원하는 결과를 검증하고 이를 블로그에 올리거나, Github page에 올리는 경우를 많이 봅니다. 그 주제가 참 멋지고 그 과정이 아름다운 분들도 많구요^^. 저도 그냥 가벼운 마음에 통계자료를 가지고 살짝 뭔가를 해볼려고 합니다. 뭐 거창한 알고리즘을 쓴 건 아니구요. 그저 그래프나 깨작거리고 그리고, 데이터의 순서나 좀 바꾸던지.. 혹은 조금 만지작 거리는 수준입니다.^^. 

살짝... "서울 강남 3구 체감안전도 높아"라는 위 기사를 보고~~~ 실제 통계자료도 그렇게 나타나는지를 볼려고 했습니다. 사람들이 생각하는 체감안전도와 혹시 통계자료에서 보는 안전도가 같을지 확인해 보는거죠^^

데이터 가져오기

공공데이터포털이라는 사이트에 가보면 아주아주 많은 통계 자료를 얻을 수 있습니다.

거기서 서울시 관서별 5대 범죄 발생 검거 현황이라는 자료가 있습니다. 그걸 받아서 사용해 볼려구요^^

데이터 다듬기 - 뭐 전처리라고 해둘까요^^

import numpy as np
import pandas as pd

import matplotlib.pyplot as plt
import seaborn as sns

import platform

from matplotlib import font_manager, rc
if platform.system() == 'Darwin':
    rc('font', family='AppleGothic')
elif platform.system() == 'Windows':
    font_name = font_manager.FontProperties(fname="c:/Windows/Fonts/malgun.ttf").get_name()
    rc('font', family=font_name)
else:
    print('Unknown system... sorry~~~~') 
    
%matplotlib inline

먼저 들어가기에 앞서~ Jupyter Notebook에서 작성할 거구요... Anaconda 4.1.1에서 테스트되었습니다^^. 그리고 자료형은 기본적으로 제가 연재로 설명한 적이 있는 pandas[바로가기]를 사용합니다. 일단, matplotlib의 한글문제를 해결하기 위해 최근 이야기한 적[바로가기]이 있는 platformimport해서 맥인지 윈도우인지를 확인하고 있습니다. 그리고...

df = pd.read_excel('data/2016서울범죄현황.xlsx', convert_float=True, encoding='euc-kr')
df.head()

아까 공공데이터 포털에서 받은 데이터는 "2016서울범죄현황.xlsx"로 저장했구요. 그 내용은 ...

이렇네요... 5대 범죄에 대해 검거와 발생 건수가 각 경찰서 별로 정리가 되어 있군요^^ 문제는 저는 각 경찰서를 각 구별로 정리를 하고 싶다는 거죠^^ 위키백과의 서울시지방경찰청[바로가기] 항목에는 서울시의 각 경찰청 리스트가 글 하단에 있습니다. 여기서 서울시 경찰청의 소속 구를 확인하구요...

SeoulGu_name = {'서대문서': '서대문구', '수서서': '강남구', '강서서': '강서구', '서초서': '서초구',
                '서부서': '은평구', '중부서': '중구', '종로서': '종로구', '남대문서': '중구',
                '혜화서': '종로구', '용산서': '용산구', '성북서': '성북구', '동대문서': '동대문구',
                '마포서': '마포구', '영등포서': '영등포구', '성동서': '성동구', '동작서': '동작구',
                '광진서': '광진구', '강북서': '강북구', '금천서': '금천구', '중랑서': '중랑구',
                '강남서': '강남구', '관악서': '관악구', '강동서': '강동구', '종암서': '성북구', 
                '구로서': '구로구', '양천서': '양천구', '송파서': '송파구', '노원서': '노원구', 
                '방배서': '서초구', '은평서': '은평구', '도봉서': '도봉구'}

df['구별'] = df['관서명'].apply(lambda v: SeoulGu_name.get(v, v))
df.head()

위에서 처럼 dict 자료형을 이용해서 구별~~이라는 column을 만들었습니다.

이제 위 결과처럼 df['구별']도 만들어 졌네요^^ 이제 '구별'로 구분은 되었지만... 구별 데이터를 쉽게 확인하기 위해서는 경찰서위주로 데이터가 되어 있는것 보다 구별로 되어있는것이 좋겠죠... 즉, 서초구처럼 경찰서가 두 개있는 구도 있으니, 전 구별로 모아서 데이터를 보고 싶다는 거죠^^. 그렇게 해주는 꽤 편리한 명령이 있습니다. .pivot_table[바로가기]입니다.^^

guDF = pd.pivot_table(df, index='구별', aggfunc=np.sum)
guDF = guDF.drop(['계'])
guDF.head()

이렇게 pivot_table을 사용하면 각 구별로 데이터를 쉽게 모아서 볼 수 있습니다. 그 결과는...

입니다.~~^^ 괜찮게 되었죠^^

guDF['강간검거율'] = guDF['강간(검거)']/guDF['강간(발생)']*100
guDF['강도검거율'] = guDF['강도(검거)']/guDF['강도(발생)']*100
guDF['살인검거율'] = guDF['살인(검거)']/guDF['살인(발생)']*100
guDF['절도검거율'] = guDF['절도(검거)']/guDF['절도(발생)']*100
guDF['폭력검거율'] = guDF['폭력(검거)']/guDF['폭력(발생)']*100

del guDF['강간(검거)']
del guDF['강도(검거)']
del guDF['살인(검거)']
del guDF['절도(검거)']
del guDF['폭력(검거)']

guDF.head()

이제 관심있는 데이터를 좀 만들고, 관심없는 데이터는 지우죠...

이렇게 되었습니다. 발생건수와 검거율만 남았네요~~~ 그런데 검거율이 100%가 넘는게 있네요... 아마 발생건수는 2016이고, 그 전해에 발생한 건수에 대한 검거가 2016에 이뤄지면 검거에 그게 반영된 모양입니다. 뭐 여기서는 그냥 100넘는건 100으로 하죠^^

guDF[guDF[['강간검거율', '강도검거율', '살인검거율', '절도검거율', '폭력검거율']] > 100] = 100
guDF.head(10)

넵~

수정되었습니다.^^.

guDF['검거율'] = guDF['소계(검거)']/guDF['소계(발생)']*100
guDF.head()

아차.. 전체 검거율도 만들어야죠~

음.. 가지고 놀만큼 되었네요^^그러나... 그냥 표가 넓어지는게 마음에 안들어서^^

guDF.rename(columns = {'강간(발생)':'강간', 
                       '강도(발생)':'강도', 
                       '살인(발생)':'살인', 
                       '절도(발생)':'절도', 
                       '폭력(발생)':'폭력'}, inplace=True)
del guDF['소계(발생)']
del guDF['소계(검거)']

guDF.head()

Column의 이름을 바꾸도록 하겠습니다.^^

앗.. 표가 확 줄어든게 마음에 드네요 ㅋㅋㅋㅋ. (이상한거에 만족합니다^^)

pop_kor.csv

위 파일을 받아서

popDF = pd.read_csv('data/pop_kor.csv', encoding='UTF-8', index_col='구별')
popDF.head()

보면...

구별 인구수가 있습니다. 어디 다른데서 사용하던건데... 필요해서 가져다 옵니다. 아마 2015년 인구라 지금이랑 맞지는 않지만, 경향정도를 확인하는 걸로 사용하도록 하겠습니다.

guDF = guDF.join(popDF)
guDF.head()

그렇게 받은 두 데이터의 index가 같기 때문에 쉽게 join 명령으로 합치도록 하겠습니다.

잘 합쳐졌죠^^ 

guDF.sort_values(by='검거율', ascending=False, inplace=True)
guDF.head()

일단.. 전체 검거율을 가지고 순위를 한 번 매겨 보겠습니다.

어때요... 종로, 용산, 서초, 등등의 구가 검거율이 높은게 아니네요... 강서구, 금천구, 강북구가.. 검거율이 높습니니다.. 응? 뭐.. 검거율이 체감안전도랑 좀 다르긴 할 수도 있겠죠.. 이제 조금더 가볼까요^^

그래프로 각 구별 현황 확인해보기

target_col = ['강간', '강도', '살인', '절도', '폭력']
weight_col = guDF[target_col].max()

crime_count_norm = guDF[target_col]/weight_col
crime_count_norm.head()

먼저... 5대범죄의 발생 건수만 대상으로 하고... 표현할려는 그래프의 특성을 잘 살리기 위해 각 범죄의 최댓값으로 각 column을 나눠서 정규화시키도록 하겠습니다.

넵... 각 범죄별 경중을 이야기할려는 것이 아니라 종합적인 시각화효과를 위해서 입니다^^

plt.figure(figsize = (10,10))
sns.heatmap(crime_count_norm.sort_values(by='살인', ascending=False), annot=True, fmt='f', linewidths=.5)
plt.title('범죄 발생(살인발생으로 정렬) - 각 항목별 최대값으로 나눠 정규화')
plt.show()

예전에 제가 연재한 적이 있는 seaborn의 heatmap[바로가기]을 사용했습니다.

비록 살인 발생 건수로 정렬했지만, 위로 갈수록 전반적으로 범죄 발생 건수가 높다는 것을 알 수 있습니다. 강남3구는 어디에 있나요^^ 네.. 결코 낮지 않네요.. 강남구는 누가봐도 5대 범죄 전체에 있어서 상위권입니다.

crime_ratio = crime_count_norm.div(guDF['인구수'], axis=0)*100000

plt.figure(figsize = (10,10))
sns.heatmap(crime_ratio.sort_values(by='살인', ascending=False), annot=True, fmt='f', linewidths=.5)
plt.title('범죄 발생(살인발생으로 정렬) - 각 항목을 정규화한 후 인구로 나눔')
plt.show()

이제 단순히 범죄건수만 보지 말고 이를 인구수로 나눠서 인구대비 발생비율로 보겠습니다.

이번에는 중구가 눈에 확~ 보이네요. 애초 기사에서 종로구에 있는 종로서가 체감안전도 1위였는데.. 종로구의 범죄발생 비율은 상위권이네요ㅠㅠ.

crime_ratio['전체발생비율'] = crime_ratio.mean(axis=1)

plt.figure(figsize = (10,10))
sns.heatmap(crime_ratio.sort_values(by='전체발생비율', ascending=False), annot=True, fmt='f', linewidths=.5)
plt.title('범죄 발생(전체발생비율로 정렬) - 각 항목을 정규화한 후 인구로 나눔')
plt.show()

이번에는 전체발생비율로 정렬하고 다시 보죠^^

확실히 알 수 있습니다. 중구, 종로구, 영등포구가 인구대비 발생비율이 높습니다. 강남구와 서초구도 만만치 않네요. 인구대비로 보니 송파는 그래도 하위권이긴 합니다.

지도에 데이터를 표현하기...

지도에 데이터를 표현하는 것도 한 번 해볼까 합니다. 예전에 제가 소개한 적이 있는 Folium[바로가기]을 이용할려구요. 이 부분을 따라가기 전에 필요한 데이터가 하나 있는데....

skorea_municipalities_geo_simple.json

입니다. 출처는 [바로가기]에 있는 한국 지도 데이터 중 서울만 제가 따로 추려낸 것입니다.

import json
import folium
import warnings
warnings.simplefilter(action = "ignore", category = FutureWarning)

geo_path = 'data/skorea_municipalities_geo_simple.json'
geo_str = json.load(open(geo_path, encoding='utf-8'))

일단 위 코드로 지도를 사용하기 위한 준비를 하구요

map = folium.Map(location=[37.5502, 126.982], zoom_start=11, tiles='Stamen Toner')

map.choropleth(geo_str = geo_str,
               data = guDF['살인'],
               columns = [guDF.index, guDF['살인']],
               fill_color = 'PuRd', #PuRd, YlGnBu
               key_on = 'feature.id')
map

심플하게 살인사건의 발생 건수를 표시해보죠

어떤거요... 갑가지 강남3구가 확 들어옵니다. 그리고 영등포구와 중랑구도 눈에 들어오네요... 저런...

map = folium.Map(location=[37.5502, 126.982], zoom_start=11, tiles='Stamen Toner')

map.choropleth(geo_str = geo_str,
               data = crime_ratio['전체발생비율'],
               columns = [crime_ratio.index, crime_ratio['전체발생비율']],
               fill_color = 'PuRd', #PuRd, YlGnBu
               key_on = 'feature.id')
map

인구대비 발생율로 계산한걸 합산한 전체발생비율로 다시 확인해 보겠습니다.

흠.. 종로구와 중구가 높네요... 강남구도 높구요... 아마 종로구와 중구는 관광 집중 지역이니 인구대비 비율이 높게 나타나는 것일 수도 있겠습니다.

map = folium.Map(location=[37.5502, 126.982], zoom_start=11, tiles='Stamen Toner')

map.choropleth(geo_str = geo_str,
               data = guDF['검거율'],
               columns = [guDF.index, guDF['검거율']],
               fill_color = 'YlGnBu', #PuRd, YlGnBu
               key_on = 'feature.id')
map

이번에는 검거율을 보죠^^

흠.. 검거율은 강서구와... 금천구, 강북구가 높네요. 

경찰서의 위치 정보에 데이터를 포함시켜서 지도에 나타내기...

처음 데이터... df라고 저장했던 데이터에는 경찰서별 정보가 남아 있습니다. 여기서... 응? '계'는 없애구요^^

이걸 가지고 경찰서의 검거율을 지도에 같이 표현해보려구요..

station_name = []

for name in df['관서명']:
    station_name.append('서울'+str(name[:-1])+'경찰서')

station_name

일단 제가 사용할 것은 googlemaps입니다. 그럴려면 경찰서의 fullname이 필요하거든요^^

이렇게 말이죠^^...

df['경찰서'] = station_name
df['검거율'] = df['소계(검거)']/df['소계(발생)']*100
df.head()

그리고.. 경찰서별 검거율을 계산해두고...

그런데.. 검거율의 폭이 좀 좁아서 가장 낮은 검거율과 가장 높은 검거율을 가지는 경찰서를 일종의 점수 개념으로 간격을 좀 벌리겠습니다. 지도에 표기할때 눈에 잘 들어나게 할려구요^^

def reRange(x, oldMin, oldMax, newMin, newMax):
    return (x - oldMin)*(newMax - newMin) / (oldMax - oldMin) + newMin

df['점수'] = reRange(df['검거율'], min(df['검거율']), max(df['검거율']), 1, 100)
df.head()

그래서 위와 같이 점수로 표기합니다. 단순히 경찰서의 능력을 검거율로만 볼수 없겠죠... 단지 얻은 데이터를 기준으로 보는 것이니까요...

이렇게 되었네요^^ 이제 sort를 시켜서 결과를 보면~

어~ 강서경찰서, 금천경찰서가 검거율 1, 2위네요... 그 뒤를 강북서, 도봉서, 수서서가 따라가고 있습니다. 이제... [바로가기]에서 소개한 데로 googlemaps를 사용해서 각 경찰서의 위도, 경도 정보를 얻을 겁니다.

import googlemaps
gmaps = googlemaps.Client(key="-- input your key --")

lat = []
lng = []

for name in df['경찰서']:
    tmpMap = gmaps.geocode(name)
    tmpLoc = tmpMap[0].get('geometry')
    lat.append(tmpLoc['location']['lat'])
    lng.append(tmpLoc['location']['lng'])
    
df['lat'] = lat
df['lng'] = lng

df.head()

위 코드의 결과는 각 경찰서의 위도 경도 정보를 얻을 수 있는거죠...

이렇게 말이죠^^...

map = folium.Map(location=[37.5502, 126.982], zoom_start=11)

for n in df.index:
    folium.CircleMarker([df['lat'][n], df['lng'][n]], radius=df['점수'][n]*25, 
                        color='#3186cc', fill_color='#3186cc').add_to(map)
    
map

이제 각 경찰서의 위치에 검거율을 환산한 점수를 원의 넓이로 표기하도록 하겠습니다.

아하.. 어떤가요.. 괜찮죠^^

map = folium.Map(location=[37.5502, 126.982], zoom_start=11)

map.choropleth(geo_str = geo_str,
               data = crime_ratio['전체발생비율'],
               columns = [crime_ratio.index, crime_ratio['전체발생비율']],
               fill_color = 'PuRd', #PuRd, YlGnBu
               key_on = 'feature.id')

for n in df.index:
    folium.CircleMarker([df['lat'][n], df['lng'][n]], radius=df['점수'][n]*25, 
                        color='#3186cc', fill_color='#3186cc').add_to(map)
    
map

마지막으로...

이렇게 아까 했던 범죄발생비율과 경찰서의 검거율을 같이 지도에 그려보았습니다. 어떤가요^^

  • 강남3구의 체감 안전도가 높다는 기사의 내용을 가지고, 실제 통계적으로도 그런 결과가 도출되는지 확인함
  • 강남3구의 5대 범죄 발생 건수는 다른 구와 비교해서 높음
  • 인구대비 발생 비율도 강남3구가 낮지는 않음
  • 단, 강남구와 서초구는 유흥업소 밀집지역에서 범죄 발생이 높을 수 있음

아무튼.. 서울시 5대 범죄 발생건수와 검거율을 가지고 잠시 즐거운 분석 시간을 가져 보았습니다. 요즘.. 제 취미활동이거든요^^


댓글을 달아 주세요

  1. 이전 댓글 더보기
  2. BlogIcon 감자튀김 2017.03.05 03:22 신고

    역시 데이터는 시각화 했을 때 이해도가 높아지는 것 같습니다.
    처리 방법도 그렇고 소스 작성도 그렇고 많이 배우고 있습니다. ^^

  3. BlogIcon IT넘버원 2017.03.05 04:26 신고

    와 정말 신기하네요.
    근데 제가 사는 지역도 보이고 항상 늘 조심해야겠네요.^^;

  4. 33 2017.03.05 15:14 신고

    이정도면 충분히 논문으로도 만들 수 있지 않을까 싶습니다
    대단하시네요..
    덕분에 간단한 웹크롤링, 공부에 도움되는 모듈 등 많이 알아갑니다
    감사합니다!

    • BlogIcon PinkWink 2017.03.06 09:41 신고

      아무런 학술적인 의미를 가지는 글은 아닙니다.. 그저 슬쩍 뭔가를 익히기 위한 학습에서 아주아주 실제에 가까운 재미있는 예제라고나 할까요^^

    • 33 2017.03.06 14:12 신고

      자료가 업데이트되면 자동화되는 시스템(프로그램)을 만든다면 어느정도 학술적 의미를 가지지 않을까요?
      아직 논문 공부하는 정도라 판단력이 좀 부족하네요 ㅠㅠ

    • BlogIcon PinkWink 2017.03.06 14:37 신고

      ㅎㅎ 아닙니다. 좋게 말씀해주셔서 살짝 겸손을 떨었습니다.
      좀 더 좋은 글을 올릴 수 있으면 좋겠습니다.^^ 애써야죠..ㅎㅎ
      즐거운 하루 되세요^^
      (아.. 데이터를 올리는 정부 공공 기관이 일관성있는 위치에 체계적으로 업로드를 해주는 건 아니라서.. 반영이 쉽지는 않더라구요^^)

  5. 허양일 2017.03.07 23:45 신고

    한가지 아쉬운게 있다면 저 통계에서는 주거라는 기준만 있지만 사실 유동인구나 유흥가의 밀집지역들을 감안할 때 이 수치들을 어떻게 가중할 것인지 생각해보시면 좋을 것 같아요. 특히 지하철 하차나 버스 하차 데이터 혹은 wifi 또는 네트워크 접속자 수, 거주 외국인 및 관광객 유입 수 등을 기반으로 예상되는 유동/누락인구까지 반영된다면, 보다 더 정확(?)한 범죄 발생률에 대한 비교가 되지 않을까 생각됩니다. 잘 보았습니다 :)

    • BlogIcon PinkWink 2017.03.08 07:49 신고

      네.. 저도 더 진행할까하다가... 일단 멈추었는데요...
      더 가고 싶었던것은...
      유동인구... 유흥업소...등의 정보와 범죄의 상관관계였습니다만..
      그건 다음 활동으로 미루도록 해야죠.. ㅎㅎ
      (언제나 그렇듯 직장인으로서... 육아도 해야하고.. 등등의 핑계입니다^^)

  6. Dave 2017.03.08 19:34 신고

    감사히 잘 배웠습니다 :)
    직접 따라해보며 상세히 살피다가 궁금증이 생겨 댓글을 남깁니다.

    df의 관서명에 따라 구 이름을 매칭시켜 df의 '구별' 열로 입력하는 과정에서,
    df['구별'] = df['관서명'].apply(lambda v: SeoulGu_name.get(v, v))
    위 람다문의 SeoulGu_name dict를 대상으로 한 .get(v, v) 안의 "v, v" 는 어떻게 이해하면 좋을까요?

    단순하게 관서명을 v로 받아 dict.get(v) 와 같이 얻을 수 있을거라 생각되는데 v가 두 번 들어가는 게 어떤 의미일지 궁금하여 여쭙습니다! :)

    • BlogIcon PinkWink 2017.03.09 08:01 신고

      네.. 그냥 인자를 v만 넣으면 없는 범위에 대해서는 None으로 처리가 되어서... 없으면 그냥 그대로 다시 출력하라는 것입니다.
      (사실 이 코드는 어디 인터넷에서 저도 본건데 꽤 유용하더라구요^^)

  7. Dave 2017.03.08 19:37 신고

    앗 방금 댓글을 달아두었는데,
    혹시 dict.get(v, v) 에서 두번째 v는 혹시라도 관할서에 해당하는 구 이름이 없을 경우 default 값으로 관할서명이 입력되도록 한 것이신지요?

  8. 또잉 2017.03.08 19:39 신고

    궁금한 점이 있습니다!

    Python을 활용한 공간정보 분석이라 그동안 고민했던 부분이 해소되었습니다.

    다만, 궁금한 점은
    구군 경계와, 경찰서 관할지역이 어긋나는 것으로 알고 있습니다.

    이 부분들이 지리정보에 반영되었는지요?

    • BlogIcon PinkWink 2017.03.09 08:03 신고

      그러지 않았습니다. 일단... 관심 지역인 강남의 경우는 거의 비슷한듯 했구요.. 나머지도 완전히 차이가 나지는 않더라구요...
      그래도 관할지역으로 표기하면 더 좋았을 수도 있겠네요....

    • 또잉 2017.03.11 16:01 신고

      감사합니다.

      재밌는 분석이어서 즐겁게 읽었습니다.

    • BlogIcon PinkWink 2017.03.12 13:04 신고

      그저 인터넷의 많은 자료를 따라하며 만들어서.. 큰 의미는 없지만..
      그래도 비슷한 방향으로 공부하시는 분들께는 가지고 놀만한 장난감이지 않을까 합니다^^

  9. BlogIcon kenu 2017.03.14 15:31 신고

    감사합니다.
    python 입문한 지 얼마 안되었는데,
    따라하기 쉽게 잘 만들어주셔서 진심으로 감사드립니다.

  10. 정재호 2017.04.20 21:07 신고

    안녕하세요.
    제가 프로그래밍을 혼자서 주먹구구식으로 배우다 이 블로그를 찾게 되어서 정말 기뻤습니다.

    제가 잘 되지 않는 게 있어서 그런데 조언 좀 구해도 될까요?
    지금 윈도우 컴퓨터로 위의 내용을 따라해 보고 있는데 seaborn을 설치할 수가 없어서 어려움을 겪고 있습니다. 제가 아진 맥북으로도 해보려고 했는데, 거기서도 seaborn 설치가 되지 않더라구요.

    제가 이해하기로는 seaborn이라는 걸 설치하면 spciy란 것도 같이 설치가 되는 것 같은데, 맥북에서는 설치 중간에 scipy 설치 과정에서 에러가 나고, 그래서 따로 scipy를 설치해주고 경로를 지정해 주어도 결국 seaborn 설치가 되지 않았구요,
    지금 윈도우 컴퓨터로는 설치하려고 하면,

    Building wheels for collected packages: scipy
    Running setup.py bdist_wheel for scipy ... error

    이런 말이 나오고, 그 다음 긴 내용의 말들이 나온 다음, 제일 마지막 부분에서는

    Command ""c:\users\sunyoung and jaeho\appdata\local\programs\python\python35-32\python.exe" -u -c "import setuptools, tokenize;__file__='C:\\Users\\SUNYOU~1\\AppData\\Local\\Temp\\pip-build-g3nhh07u\\scipy\\setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record C:\Users\SUNYOU~1\AppData\Local\Temp\pip-8t0usrqy-record\install-record.txt --single-version-externally-managed --compile" failed with error code 1 in C:\Users\SUNYOU~1\AppData\Local\Temp\pip-build-g3nhh07u\scipy\

    라는 말이 나오고, 결과적으로는 설치가 되지 않더라구요.

    제가 구글로 검색해 봐도 아직 해결하지 못하고 있는데, 혹시 조언을 해 주실 수 있으세요?

    감사합니다!

  11. 정재호 2017.04.20 21:25 신고

    안녕하세요, 조금 전에 글 남겼던 정재호인데요..^^;
    제가 anaconda라는 걸 설치하고, anaconda promt를 실행시켜서 seaborn을 설치하려고 하니 이미 설치되어 있다고 나오더라구요. 그래서 확인해 보려고 python을 실행시키고 import seaborn을 실행시키니 ValueError: _getfullpathname: embedded null character in path 라는 말을 포함한 긴 내용이 나오고 결국 실행이 안되더라구요..

    조금 진척이 있었던 것 같은데, 혹시 지금 단계에서 어떤 걸 하면 좋을지 조언해 주실 수 있으세요? 감사합니다!

    • BlogIcon PinkWink 2017.04.21 06:14 신고

      만약 기존에 따로 python을 설치하고 또 여러 모듈을 설치하고.. 그리고 다시 아나콘다를 설치하고... 하면... 버젼관리가 안되서 알 수 없는 여러 에러가 나더라구요.ㅠㅠ. 기존의 python을 지우고 환경설정에서 기존 python에 대한 환경변수도 삭제하고 다시 conda install을 실행해 보시는 것은 어떨까요?

  12. 정재호 2017.04.21 07:30 신고

    답변 감사드립니다!!


    다행히 제가 하고자 하는 부분인 지도에 수치를 표현하는 것에는 크게 영향이 없는 것 같더라구요.. 그래서 일단 좌표를 얻는 것까지는 성공했습니다.

    조금만 더 여쭤봐도 될까요?^^;;

    제가 지도에 데이터 표시하기 부분을 할 때 에러 없이 지나간 걸로 봐서는 된 것 같긴 한데요.. 수정된 그림은 어떻게 확인하면 되는 거에요?^^;; 그리고 저는 명령어 창에서 파이썬 코드를 실행하면 >>> 가 뜨는 창에서 내용들이 출력이 되는데, 여기 올려주신 것처럼 깔끔하게 표로 보이게 하는 거랑 그림을 출력하는 방법은 찾아봐도 나오질 않더라구요.. 이 부분 좀 알려주실 수 있으세요?

    정말 감사합니다. 저는 경제학을 공부하는 학생인데요, 여기 블로그를 알게 되어서 정말 기쁘기고, 오히려 저보다 더 잘 하시는 것 같아서 부럽기도 합니다.


    감사합니다!!

    • BlogIcon PinkWink 2017.04.21 10:08 신고

      여기( http://pinkwink.kr/940 ) 있듯이 저는 아나콘다 4.1.1을 설치 했구요... 그리고 DataScience 카테고리는 Jupyter로 코드를 작성해서 보여드리고 있습니다.^^ http://pinkwink.kr/946 입니다.^^

  13. 정재호 2017.04.22 01:51 신고

    안녕하세요. ^^;;

    제가 알려주신 대로 주피터를 설치했는데 윈도우 컴퓨터랑 맥 둘 모두에서 툴? 이 안보이더라구요.. 실행할 수 있는 방법 자체가 없고 명령어만 입력할 수 있는 상황이어서, 다시 구글로 찾아보고 기존에 설치되어 있던 파이썬과 아나콘다를 삭제하고 다시 실행해 봤는데 여전히 이 문제를 해결하지 못하고 있어요.. ;

    혹시 이 문제는 어떻게 해결할 수 있는지 아세요? ^^;; 제가 본문과 관련 없는 부분에서 계속 문제가 생기니까 컴퓨터가 이상한 건지, 아니면 제가 뭔가 중요한 걸 잘못하고 있는건지 잘 구분이 안되네요.. ^^;;

    감사합니다!!

  14. 정재호 2017.04.22 11:52 신고

    아, 제가 바보였네요..;;; 스파이더의 오른편에 나오는 실행결과 부분을 보면 되는 거였네요..;
    감사합니다!! ^^;;

  15. BlogIcon 한도림 2017.12.08 14:17 신고

    안녕하세요 파이썬 공부중인 학생입니다.
    이 게시글에 있는
    "서울시 경찰서별 5대범죄 발생, 검거..." 이
    공공데이터에서 없어진거 같습니다.
    공부를 위해서 "서울시 경찰서별 5대범죄 발생, 검거....".csv or .xlsx 파일을 주실수 있습나요?
    myesung12@naver.com 입니다.

    • BlogIcon PinkWink 2017.12.08 18:49 신고

      블로그 제일 상단에 github 링크가 있습니다. 아이콘으로.. 거기 가셔서 DataScience라는 폴더에 보면 데이터가 있을 겁니다.

  16. WerBer 2018.01.05 09:47 신고

    초반에 엑셀파일 read할 때 'data/2016...' 쓰셨는데 저 data폴더는 어디에 위치시키신건가요....

    • BlogIcon PinkWink 2018.01.05 09:58 신고

      이 코드에서는 소스코드가 위치하는 폴더와 같은 곳일 겁니다.

    • WerBer 2018.01.05 10:03 신고

      빠른답변 감사합니다ㅠㅠ
      그럼 jupyter가 위치한곳 이라는건가요???

      C:\Anaconda3\envs\python3\lib\site-packages\pandas\io\excel.py in read_excel 이렇게 떠서 pandas 폴더에 넣었는데 계속 에러가 나네요

    • BlogIcon PinkWink 2018.01.05 10:30 신고

      아니요.. 작성하고 계신 소스코드가 위치한 폴더입니다. (프로그램이 설치된 폴더가 아닌..)

  17. 파이썬입문자 2018.04.03 15:37 신고

    핑크윙크님 항상 좋은 자료 올려주셔서 많은 도움을 받고 있습니다. 감사합니다.
    지도를 만드는 map.choropleth까지 입력을 하고 출력받는 가운데 오류가 자꾸 발생합니다.
    1) 지도가 뜨지만 지도의 색깔이 한 색으로 표시되거나
    2) 오류의 설명으로: '<' not supported between instances of 'str' and 'int', float을 제외한 int형식은 입력되지 않는다.
    두 가지 오류가 계속 발생하는데,
    혹시 이 문제가 무엇때문인지, 어떻게 해결하면 되는지 알려주실 수 있으신가요?ㅠㅠ

    • BlogIcon PinkWink 2018.04.05 00:17 신고

      흠.. 혹시 ... 수치로 된 데이터가 올바르게 수치형인지 확인해 보세요.. 데이터가 pandas 데이터프레임이면 info 명령으로 해당 컬럼의 데이터형을 알 수 있습니다.

    • 파이썬입문자 2018.04.10 14:52 신고

      info 명령어에 넣는 데이터의 형식을 잘 이해하지 못하여서ㅠ exel에서 데이터를 숫자로 바꾸고 맵으로 다시 확인해보았습니다.
      index의 범위가 나오는 것을 보면 숫자로 읽히는 것 같은데, 혹시 수치형으로 되지 않은게 아니라면 무엇이 문제일까요..?
      아래 map그림을 첨부합니다.

      https://docs.google.com/document/d/1GZrl2GpqhrxzgyRaBIhyPjgvqgAkxpYh6QHVLrPEmI8/edit?usp=sharing

    • BlogIcon PinkWink 2018.04.12 00:20 신고

      실제 데이터가 수치형인지 확인하셔야 합니다.
      info() 명령의 결과를 보면 숫자인 컬럼은 float이나 int라고 되어 있습니다.

  18. 2018.05.28 22:12

    비밀댓글입니다

  19. song 2018.06.04 11:55 신고

    안녕하세요 도서를 참고하며 공부를 해나가고 있는 중 궁금한 점이 생겨 질문드립니다
    pivot_table을 이용하여 데이터를 관서별에서 구별로 바꾸는 과정에서 데이터가 누락되는 문제점이 발생하는데, 왜 이런 누락이 발생하는지 모르겠습니다.

    crime_anal_raw=pd.read_csv('D:/pydata/crime_in_Seoul_gu_name.csv',encoding='utf-8',index_col=0)
    를 이용하면 다음과 같이

    관서명 살인 발생 살인 검거 강도 발생 강도 검거 ... 절도 발생 절도 검거 폭력 발생 폭력 검거 구별
    0 중부서 2 2 3 2 ... 1,395 477 1,355 1,170 중구
    1 종로서 3 3 6 5 ... 1,070 413 1,278 1,070 종로구
    2 남대문서 1 0 6 4 ... 1,153 382 869 794 중구
    3 서대문서 2 2 5 4 ... 1,812 738 2,056 1,711 서대문구

    출력됨을 확인하였습니다.

    그런데, pivot_table을 이용하여 구별로 바꾸는 과정에서 절도와 폭력이 누락되는 현상이 발생합니다.
    crime_anal=pd.pivot_table(crime_anal_raw,index='구별',aggfunc=np.sum)
    를 이용하여 crime_anal을 출력해보면

    [31 rows x 12 columns]
    강간 검거 강간 발생 강도 검거 강도 발생 살인 검거 살인 발생
    구별
    강남구 349 449 18 21 10 13
    강동구 123 156 8 6 3 4
    강북구 126 153 13 14 8 7
    관악구 221 320 14 12 8 9
    와 같이 출력됩니다. 12colums가 존재한다고는 하는데 다음 코드인

    crime_anal['강간검거율']=crime_anal['강간 검거']/crime_anal['강간 발생']*100
    crime_anal['강도검거율']=crime_anal['강도 검거']/crime_anal['강도 발생']*100
    crime_anal['살인검거율']=crime_anal['살인 검거']/crime_anal['살인 발생']*100
    crime_anal['절도검거율']=crime_anal['절도 검거']/crime_anal['절도 발생']*100
    crime_anal['폭력검거율']=crime_anal['폭력 검거']/crime_anal['폭력 발생']*100
    에서 절도가 존재하지 않아 오류가 발생하였다 라는 오류가 발생합니다.

    다음은 오류 로그입니다.
    Traceback (most recent call last):
    File "C:\Users\Admin\PycharmProjects\SeoulCriminal\venv\lib\site-packages\pandas\core\indexes\base.py", line 3063, in get_loc
    return self._engine.get_loc(key)
    File "pandas\_libs\index.pyx", line 140, in pandas._libs.index.IndexEngine.get_loc
    File "pandas\_libs\index.pyx", line 162, in pandas._libs.index.IndexEngine.get_loc
    File "pandas\_libs\hashtable_class_helper.pxi", line 1492, in pandas._libs.hashtable.PyObjectHashTable.get_item
    File "pandas\_libs\hashtable_class_helper.pxi", line 1500, in pandas._libs.hashtable.PyObjectHashTable.get_item
    KeyError: '절도 검거'

    왜 이런 현상이 발생하는지 궁금하여 질문드립니다.

    • BlogIcon PinkWink 2018.06.04 12:29 신고

      crime_anal.info()
      명령을 수행해서
      사라진다는 컬럼을 확인해보세요
      아마 숫자(float)가 아니라 문자(object)로 되어 있을 수 있습니다.
      pivot_table은 숫자만 value로 바꿔주거든요.
      일단 제가 생각한 상황이 맞는지 info() 명령으로 확인해 주세요.

    • song 2018.06.04 13:48 신고

      생각하신 문제가 맞습니다.
      .info()로 확인해보니 절도와 폭력 부분이 object 형입니다.
      1000이 넘는 숫자는 1,000의 형식으로 표현하려하는데 csv파일이라 큰따옴표로 묶여있어서 숫자가 아닌 문자로 인식된 것 같습니다.

    • BlogIcon PinkWink 2018.06.04 13:54 신고

      그러면 read_csv를 할 때, thousands=',' 라고 옵션을 주시면 됩니다. 천단위에 콤마가 찍혀있는데 무시하라는 뜻입니다.

    • song 2018.06.04 14:03 신고

      감사합니다!
      손으로 다 바꾸고 댓글 확인했네요 ㅋㅋ
      다음부터는 thousans=',' 를 사용해야겠습니다

    • BlogIcon PinkWink 2018.06.04 14:11 신고

      ㅎㅎ 네... 화이팅입니다.^^

  20. tina 2018.06.07 19:49 신고

    "서울시 경찰서별 5대범죄 발생, 검거..." 이
    공공데이터에서 없어진거 같습니다.
    공부를 위해서 "서울시 경찰서별 5대범죄 발생, 검거....".csv or .xlsx
    답글에서 말씀하시는 다운받을 수 잇다는 폴더도 못 찾겠어요..
    wlgid94@gmail.com
    혹시 보내주실수잇을까요?

  21. 닉기 2018.08.12 16:54 신고

    안녕하세요 집필해주신 교재 덕분에 재밌게 공부하고 있습니다
    한가지 질문이 있는데요 교재 80p In[5] 에서 gmaps.geocode('서울중부경찰서', language='ko'를 치면
    결과가 잘나오는데 '서울중부경찰서'를 제외한 다른 경찰서(예를 들면 '서울종로경찰서')를 치면
    결과가 안나오는 이유는 뭘까요??
    그로인해 82p In[7]을 치면 Out[7]로 뜨지않고 첫번째줄만 뜨고 오류가 나더군요
    그리고 geocode(' ') 이부분에 다른 장소를 치면 안되는건가요? 마찬가지로 오류가 뜹니다