데이터분석/미니프로젝트 01. 서울시 CCTV 현황 분석

미니프로젝트 01-02-03. googlemaps에서 구별 정보를 얻어 데이터 정리, 구별데이터로 변경하기

책다니엘 2024. 3. 26. 00:43

1. 다시 데이터 분석으로 돌아오자. google maps를 활용해서 주소와 위치정보를 얻어 온다.

단순 테스트, 서울영등포경찰서의 지리정보를 잘 얻어온다

2. tmp = gmaps.geocode('서울영등포경찰서', language='ko') 명령어로 tmp변수를 선언해준다. API를 통해 데이터를 얻어오는 작업이다. 전체 결과의 크기가 1인 list형 데이터기 때문에, tmp[0]으로 접근해야 한다.(큰 리스트 안에 dict형으로 들어가 있다.) 따라서 정보를 얻어올 때도 dic에서 데이터를 얻어오는 get명령을 사용해서 접근한다.

latitude는 위도(상하), longitude는 경도(좌우)

3. 또한 전체 주소에서 필요한 구 이름만 가져와보자.

 

4. 이전에 지정했던 crime_station 데이터프레임 옆에 새로운 컬럼을 추가하자. '구별', 'lat(위도)', 'lng(경도)' 세 개의 컬럼을 추가한다. 일단 아무것도 없는 값을 채워주는데, 이때는 np.nan을 넣어 준다.

 

5. 이전에 pandas에서 반복문을 쓸 때는 iterrows()를 쓰는 것이 좋다고 했다.(데이터분석 카테고리 중급 반복문 글 참고) pandas에서 iterrows()를 통해 반복문으로 '구별', 'lat', 'lng'컬럼에 데이터를 넣어줄 것이다. 반복문이 잘 돌고 있는지 확인하기 위해 count+=1를 print하게 할 것이다. 이를 코드로 작성하면 다음과 같다. 

 

* 이전에 만들었던 피벗테이블에서 idx는 '강남', '강북' 등의 지역이름이다. 여기에 '서울'과 '경찰서'를 합쳐서 '서울강남경찰서', '서울강북경찰서', ... 등의 str을 만들어준 다음, 이를 gmaps.geocode()명령어에 집어넣어 tmp변수로 해당 경찰서의 지리정보를 불러온다. 우리는 '구별', 'lat', 'lng' 세 가지 컬럼을 추가할 것이므로, 각각 tmp[0].get으로 dic개체인 경찰서지리정보의 정보들을 불러온다. 그 다음 crime_station데이터프레임에서 행과 열로 데이터를 선택하는 명령어인 .loc[row_label, column_label]을 통해 해당 경찰서의 '구별', 'lat', 'lng' 컬럼의 적절한 위치에 tmp_gu, lat, lng를 넣어 준다. 정보가 잘 입력되고 있으면 콘솔에서 0,1,2,3, ... 등 숫자를 계속 출력한다.

6. .head()명령어로 다시 데이터를 불러오면 다음과 같다.

7. 이제 멀티컬럼을 하나로 합치는 작업을 한다. 예를 들어 '강도' 컬럼의 하위 컬럼인 '검거', '발생'을 합쳐 '강도검거', '강도발생' 컬럼으로 만드는 것이다. 

깔끔하게 정리되었다.

8. 마지막으로 저장해준다. 코드는 다음과 같다.

crime_station.to_csv('../data/02. Crime_In_Seoul.csv', sep=',', encoding='utf-8')

 


 

9. 지금까지는 '구'별로 데이터를 정렬하여 각 서당 범죄 검거건수, 발생건수, 위도와 경도 정보를 얻어 왔다. 그런데 서울은 한 구에 경찰서가 두 개소인 곳이 있다. 그러므로 구의 이름에 따라 다시 정렬해야 한다. 

아까 저장한 데이터를 다시 crime_anal_station으로 불러오자

 

10. 다시 .pivot_table()로 데이터를 피벗테이블로 다시 정렬하자. 이번에는 인덱스를 '구별'로 하고, pivot_table의 func을 sum으로 잡자. 현재 필요없는 lat, lng 테이블은 삭제하자.(피벗테이블의 aggfunc=[np.sum]때문에 lat과 lng도 같이 합산한다)

11. 이제 검거율을 만들어 보자. 일단 첫 번째로 단순계산을 해보자.

 

12. 이 때 사용할만한 좋은 표현이 있다. 만약에 하나의 컬럼을 다른 컬럼으로 나누고 싶다면 이런 표현을 쓰면 좋다.

 

13. 그렇다면 만약 다수의 컬럼을 다른 컬럼으로 나누고 싶다면 어떻게 하는가? 이런 표현도 있다.

(코드 한 줄만으로 분모와 분자 모두 배열의 순서에 따라 나눈 값을 전달하다니, 정말 좋은 기능이다!)

num = numerator(분자), den = denominator(분모)

14. 결과적으로 해당 코드를 활용하면 이런 결과가 나온다. 

 

15. 검거율 컬럼을 만들었으니 검거 칼럼은 필요가 없다. 전부 삭제하자. 

필요없는 컬럼들을 지웠다

 

16. 두 번째 문제는, '강북구'의 '강도검거율', '강동구'의 '살인검거율'의 경우 100이 넘는 것을 볼 수 있다. 예를 들어, 작년에 발생한 범죄의 경우, '발생'은 작년 데이터에 잡히지만 '검거'는 올해 데이터에 잡히므로 검거율이 100을 넘을 수는 있다. 이런 경우 발생연도/검거연도를 구분하고 분석해야겠지만, 이번 프로젝트는 그런 데이터까지는 목표가 아니며, 단순히 heatmap 등의 데이터시각화 시에 문제가 될 수 있는 문제로 인해, 강제로 100 이상의 수치는 100으로 고정하기로 한다. 

 

* pandas의 버전과 dependency에 따라 위 코드가 동작하지 않을 때도 있다.(업데이트가 대부분 완료된 현재는 잘 일어나지 않는 문제이긴 하지만) 그럴 때는 아래 코드를 적어주면 된다. 

target = ['강간검거율', '강도검거율', '살인검거율', '절도검거율', '폭력검거율']
for column in con_list:
    crime_anal_gu.loc[crime_anal_gu[target] > 100, column] = 100

 

17. 컬럼명들을 단순화해주자.