Project 2 - 서울시 범죄 현황 데이터 분석 (2)
📖 Pandas에 잘 맞춰진 반복문용 명령어 : iterrows()
- Pandas 데이터 프레임 대부분은 2차원이므로 for문을 사용하면 가독률 ↓
∴ Pandas 데이터 프레임으로 반복문을 만들때는 iterrows()를 권장 (인덱스와 내용으로 구분)
—
Google Maps를 이용한 데이터 정리
구별, lat, lng 컬럼 추가
crime_station["구별"] = np.nan
crime_station["lat"] = np.nan
crime_station["lng"] = np.nan
crime_station.head()
| 죄종 | 강간 | 강도 | 살인 | 절도 | 폭력 | 구별 | lat | lng | |||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 발생검거 | 검거 | 발생 | 검거 | 발생 | 검거 | 발생 | 검거 | 발생 | 검거 | 발생 | |||
| 구분 | |||||||||||||
| 강남 | 269.0 | 339.0 | 26.0 | 24.0 | 3.0 | 3.0 | 1129.0 | 2438.0 | 2096.0 | 2336.0 | NaN | NaN | NaN |
| 강동 | 152.0 | 160.0 | 13.0 | 14.0 | 5.0 | 4.0 | 902.0 | 1754.0 | 2201.0 | 2530.0 | NaN | NaN | NaN |
| 강북 | 159.0 | 217.0 | 4.0 | 5.0 | 6.0 | 7.0 | 672.0 | 1222.0 | 2482.0 | 2778.0 | NaN | NaN | NaN |
| 강서 | 239.0 | 275.0 | 10.0 | 10.0 | 10.0 | 9.0 | 1070.0 | 1952.0 | 2768.0 | 3204.0 | NaN | NaN | NaN |
| 관악 | 264.0 | 322.0 | 10.0 | 12.0 | 7.0 | 6.0 | 937.0 | 2103.0 | 2707.0 | 3235.0 | NaN | NaN | NaN |
iterrows()
- 경찰서 이름으로 소속된 구 이름 얻기
- 구 이름, 위도, 경도 정보 저장
- 반복문으로 NaN 채우기
count = 0
for idx, rows in crime_station.iterrows():
station_name = "서울" + str(idx) + "경찰서"
tmp = gmaps.geocode(station_name, language="ko")
tmp_gu = tmp[0].get("formatted_address")
lat = tmp[0].get("geometry")["location"]["lat"]
lng = tmp[0].get("geometry")["location"]["lng"]
if count == 4:
crime_station.loc[idx, "구별"] = "관악구"
else:
crime_station.loc[idx, "lat"] = lat
crime_station.loc[idx, "lng"] = lng
crime_station.loc[idx, "구별"] = tmp_gu.split()[2]
print(count)
count += 1
crime_station.head()
| 강간검거 | 강간발생 | 강도검거 | 강도발생 | 살인검거 | 살인발생 | 절도검거 | 절도발생 | 폭력검거 | 폭력발생 | 구별 | lat | lng | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 구분 | |||||||||||||
| 강남 | 269.0 | 339.0 | 26.0 | 24.0 | 3.0 | 3.0 | 1129.0 | 2438.0 | 2096.0 | 2336.0 | 강남구 | 37.509435 | 127.066958 |
| 강동 | 152.0 | 160.0 | 13.0 | 14.0 | 5.0 | 4.0 | 902.0 | 1754.0 | 2201.0 | 2530.0 | 강동구 | 37.528511 | 127.126822 |
| 강북 | 159.0 | 217.0 | 4.0 | 5.0 | 6.0 | 7.0 | 672.0 | 1222.0 | 2482.0 | 2778.0 | 강북구 | 37.637304 | 127.027340 |
| 강서 | 239.0 | 275.0 | 10.0 | 10.0 | 10.0 | 9.0 | 1070.0 | 1952.0 | 2768.0 | 3204.0 | 양천구 | 37.539783 | 126.829997 |
| 관악 | 264.0 | 322.0 | 10.0 | 12.0 | 7.0 | 6.0 | 937.0 | 2103.0 | 2707.0 | 3235.0 | 관악구 | 37.474395 | 126.951349 |
데이터 정리
crime_station.columns.get_level_values(0)[2] + crime_station.columns.get_level_values(1)[2]
len(crime_station.columns.get_level_values(0))
'강도검거'
13
tmp = [
crime_station.columns.get_level_values(0)[n] + crime_station.columns.get_level_values(1)[n]
for n in range(0, len(crime_station.columns.get_level_values(0)))
]
tmp, len(tmp)
(['강간검거',
'강간발생',
'강도검거',
'강도발생',
'살인검거',
'살인발생',
'절도검거',
'절도발생',
'폭력검거',
'폭력발생',
'구별',
'lat',
'lng'],
13)
crime_station.columns = tmp
crime_station.head()
| 강간검거 | 강간발생 | 강도검거 | 강도발생 | 살인검거 | 살인발생 | 절도검거 | 절도발생 | 폭력검거 | 폭력발생 | 구별 | lat | lng | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 구분 | |||||||||||||
| 강남 | 269.0 | 339.0 | 26.0 | 24.0 | 3.0 | 3.0 | 1129.0 | 2438.0 | 2096.0 | 2336.0 | 강남구 | 37.509435 | 127.066958 |
| 강동 | 152.0 | 160.0 | 13.0 | 14.0 | 5.0 | 4.0 | 902.0 | 1754.0 | 2201.0 | 2530.0 | 강동구 | 37.528511 | 127.126822 |
| 강북 | 159.0 | 217.0 | 4.0 | 5.0 | 6.0 | 7.0 | 672.0 | 1222.0 | 2482.0 | 2778.0 | 강북구 | 37.637304 | 127.027340 |
| 강서 | 239.0 | 275.0 | 10.0 | 10.0 | 10.0 | 9.0 | 1070.0 | 1952.0 | 2768.0 | 3204.0 | 강서구 | 37.539783 | 126.829997 |
| 관악 | 264.0 | 322.0 | 10.0 | 12.0 | 7.0 | 6.0 | 937.0 | 2103.0 | 2707.0 | 3235.0 | 관악구 | 37.474395 | 126.951349 |
데이터 저장
crime_station.to_csv("../data/02. crime_in_Seoul_raw.csv", sep=",", encoding="utf-8")
구별 데이터로 정리
crime_anal_station = pd.read_csv(
"../data/02. crime_in_Seoul_raw.csv", index_col=0, encoding="utf-8") # index_col "구분"을 인덱스 컬럼으로 설정
crime_anal_station.head()
| 강간검거 | 강간발생 | 강도검거 | 강도발생 | 살인검거 | 살인발생 | 절도검거 | 절도발생 | 폭력검거 | 폭력발생 | 구별 | lat | lng | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 구분 | |||||||||||||
| 강남 | 269.0 | 339.0 | 26.0 | 24.0 | 3.0 | 3.0 | 1129.0 | 2438.0 | 2096.0 | 2336.0 | 강남구 | 37.509435 | 127.066958 |
| 강동 | 152.0 | 160.0 | 13.0 | 14.0 | 5.0 | 4.0 | 902.0 | 1754.0 | 2201.0 | 2530.0 | 강동구 | 37.528511 | 127.126822 |
| 강북 | 159.0 | 217.0 | 4.0 | 5.0 | 6.0 | 7.0 | 672.0 | 1222.0 | 2482.0 | 2778.0 | 강북구 | 37.637304 | 127.027340 |
| 강서 | 239.0 | 275.0 | 10.0 | 10.0 | 10.0 | 9.0 | 1070.0 | 1952.0 | 2768.0 | 3204.0 | 양천구 | 37.539783 | 126.829997 |
| 관악 | 264.0 | 322.0 | 10.0 | 12.0 | 7.0 | 6.0 | 937.0 | 2103.0 | 2707.0 | 3235.0 | 관악구 | 37.474395 | 126.951349 |
crime_anal_gu = pd.pivot_table(crime_anal_station, index="구별", aggfunc=np.sum)
del crime_anal_gu["lat"]
crime_anal_gu.drop("lng", axis=1, inplace=True)
crime_anal_gu.head()
| 강간검거 | 강간발생 | 강도검거 | 강도발생 | 살인검거 | 살인발생 | 절도검거 | 절도발생 | 폭력검거 | 폭력발생 | |
|---|---|---|---|---|---|---|---|---|---|---|
| 구별 | ||||||||||
| 강남구 | 413.0 | 516.0 | 42.0 | 39.0 | 5.0 | 5.0 | 1918.0 | 3587.0 | 3527.0 | 4002.0 |
| 강동구 | 152.0 | 160.0 | 13.0 | 14.0 | 5.0 | 4.0 | 902.0 | 1754.0 | 2201.0 | 2530.0 |
| 강북구 | 159.0 | 217.0 | 4.0 | 5.0 | 6.0 | 7.0 | 672.0 | 1222.0 | 2482.0 | 2778.0 |
| 관악구 | 264.0 | 322.0 | 10.0 | 12.0 | 7.0 | 6.0 | 937.0 | 2103.0 | 2707.0 | 3235.0 |
| 광진구 | 234.0 | 279.0 | 6.0 | 11.0 | 4.0 | 4.0 | 1057.0 | 2636.0 | 2011.0 | 2392.0 |
검거율 생성
- 하나의 컬럼을 다른 컬럼으로 나누기 ```py crime_anal_gu[“강도검거”] / crime_anal_gu[“강도발생”]
구별 강남구 1.076923 강동구 0.928571 강북구 0.800000 관악구 0.833333 광진구 0.545455 구로구 1.300000 금천구 1.000000 노원구 1.500000 도봉구 1.000000 동대문구 1.200000 동작구 1.000000 마포구 1.750000 서대문구 0.800000 서초구 0.769231 성동구 1.666667 성북구 1.000000 송파구 0.800000 양천구 1.000000 영등포구 0.736842 용산구 1.111111 은평구 0.777778 종로구 0.750000 중구 0.875000 중랑구 1.000000 dtype: float64
---
- 다수의 컬럼을 다른 컬럼으로 나누기
```py
crime_anal_gu[["강도검거", "살인검거"]].div(crime_anal_gu["강도발생"], axis=0).head(3)
| 강도검거 | 살인검거 | |
|---|---|---|
| 구별 | ||
| 강남구 | 1.076923 | 0.128205 |
| 강동구 | 0.928571 | 0.357143 |
| 강북구 | 0.800000 | 1.200000 |
- 다수의 컬럼을 다수의 컬럼으로 각각 나누기 ```py num =[“강간검거”, “강도검거”, “살인검거”, “절도검거”, “폭력검거”] den =[“강간발생”, “강도발생”, “살인발생”, “절도발생”, “폭력발생”]
crime_anal_gu[num].div(crime_anal_gu[den].values).head()
<div>
<style scoped="">
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
</style>
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>강간검거</th>
<th>강도검거</th>
<th>살인검거</th>
<th>절도검거</th>
<th>폭력검거</th>
</tr>
<tr>
<th>구별</th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<th>강남구</th>
<td>0.800388</td>
<td>1.076923</td>
<td>1.000000</td>
<td>0.534709</td>
<td>0.881309</td>
</tr>
<tr>
<th>강동구</th>
<td>0.950000</td>
<td>0.928571</td>
<td>1.250000</td>
<td>0.514253</td>
<td>0.869960</td>
</tr>
<tr>
<th>강북구</th>
<td>0.732719</td>
<td>0.800000</td>
<td>0.857143</td>
<td>0.549918</td>
<td>0.893449</td>
</tr>
<tr>
<th>관악구</th>
<td>0.819876</td>
<td>0.833333</td>
<td>1.166667</td>
<td>0.445554</td>
<td>0.836785</td>
</tr>
<tr>
<th>광진구</th>
<td>0.838710</td>
<td>0.545455</td>
<td>1.000000</td>
<td>0.400986</td>
<td>0.840719</td>
</tr>
</tbody>
</table>
</div>
```py
target = ["강간검거율", "강도검거율", "살인검거율", "절도검거율", "폭력검거율"]
num =["강간검거", "강도검거", "살인검거", "절도검거", "폭력검거"]
den =["강간발생", "강도발생", "살인발생", "절도발생", "폭력발생"]
crime_anal_gu[target] = crime_anal_gu[num].div(crime_anal_gu[den].values) * 100
crime_anal_gu.head()
| 강간검거 | 강간발생 | 강도검거 | 강도발생 | 살인검거 | 살인발생 | 절도검거 | 절도발생 | 폭력검거 | 폭력발생 | 강간검거율 | 강도검거율 | 살인검거율 | 절도검거율 | 폭력검거율 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 구별 | |||||||||||||||
| 강남구 | 413.0 | 516.0 | 42.0 | 39.0 | 5.0 | 5.0 | 1918.0 | 3587.0 | 3527.0 | 4002.0 | 80.038760 | 107.692308 | 100.000000 | 53.470867 | 88.130935 |
| 강동구 | 152.0 | 160.0 | 13.0 | 14.0 | 5.0 | 4.0 | 902.0 | 1754.0 | 2201.0 | 2530.0 | 95.000000 | 92.857143 | 125.000000 | 51.425314 | 86.996047 |
| 강북구 | 159.0 | 217.0 | 4.0 | 5.0 | 6.0 | 7.0 | 672.0 | 1222.0 | 2482.0 | 2778.0 | 73.271889 | 80.000000 | 85.714286 | 54.991817 | 89.344852 |
| 관악구 | 264.0 | 322.0 | 10.0 | 12.0 | 7.0 | 6.0 | 937.0 | 2103.0 | 2707.0 | 3235.0 | 81.987578 | 83.333333 | 116.666667 | 44.555397 | 83.678516 |
| 광진구 | 234.0 | 279.0 | 6.0 | 11.0 | 4.0 | 4.0 | 1057.0 | 2636.0 | 2011.0 | 2392.0 | 83.870968 | 54.545455 | 100.000000 | 40.098634 | 84.071906 |
필요없는 칼럼 제거
del crime_anal_gu["강간검거"]
del crime_anal_gu["강도검거"]
crime_anal_gu.drop(["살인검거", "절도검거", "폭력검거"], axis=1, inplace=True)
crime_anal_gu.head()
| 강간발생 | 강도발생 | 살인발생 | 절도발생 | 폭력발생 | 강간검거율 | 강도검거율 | 살인검거율 | 절도검거율 | 폭력검거율 | |
|---|---|---|---|---|---|---|---|---|---|---|
| 구별 | ||||||||||
| 강남구 | 516.0 | 39.0 | 5.0 | 3587.0 | 4002.0 | 80.038760 | 107.692308 | 100.000000 | 53.470867 | 88.130935 |
| 강동구 | 160.0 | 14.0 | 4.0 | 1754.0 | 2530.0 | 95.000000 | 92.857143 | 125.000000 | 51.425314 | 86.996047 |
| 강북구 | 217.0 | 5.0 | 7.0 | 1222.0 | 2778.0 | 73.271889 | 80.000000 | 85.714286 | 54.991817 | 89.344852 |
| 관악구 | 322.0 | 12.0 | 6.0 | 2103.0 | 3235.0 | 81.987578 | 83.333333 | 116.666667 | 44.555397 | 83.678516 |
| 광진구 | 279.0 | 11.0 | 4.0 | 2636.0 | 2392.0 | 83.870968 | 54.545455 | 100.000000 | 40.098634 | 84.071906 |
검거율 100보다 큰 숫자 변경
crime_anal_gu[crime_anal_gu[target] > 100] = 100
crime_anal_gu.head()
| 강간발생 | 강도발생 | 살인발생 | 절도발생 | 폭력발생 | 강간검거율 | 강도검거율 | 살인검거율 | 절도검거율 | 폭력검거율 | |
|---|---|---|---|---|---|---|---|---|---|---|
| 구별 | ||||||||||
| 강남구 | 516.0 | 39.0 | 5.0 | 3587.0 | 4002.0 | 80.038760 | 100.000000 | 100.000000 | 53.470867 | 88.130935 |
| 강동구 | 160.0 | 14.0 | 4.0 | 1754.0 | 2530.0 | 95.000000 | 92.857143 | 100.000000 | 51.425314 | 86.996047 |
| 강북구 | 217.0 | 5.0 | 7.0 | 1222.0 | 2778.0 | 73.271889 | 80.000000 | 85.714286 | 54.991817 | 89.344852 |
| 관악구 | 322.0 | 12.0 | 6.0 | 2103.0 | 3235.0 | 81.987578 | 83.333333 | 100.000000 | 44.555397 | 83.678516 |
| 광진구 | 279.0 | 11.0 | 4.0 | 2636.0 | 2392.0 | 83.870968 | 54.545455 | 100.000000 | 40.098634 | 84.071906 |
컬럼 이름 변경
crime_anal_gu.rename(
columns={"강간발생": "강간", "강도발생": "강도", "살인발생": "살인", "절도발생": "절도", "폭력발생": "폭력"},
inplace=True)
crime_anal_gu.head()
| 강간 | 강도 | 살인 | 절도 | 폭력 | 강간검거율 | 강도검거율 | 살인검거율 | 절도검거율 | 폭력검거율 | |
|---|---|---|---|---|---|---|---|---|---|---|
| 구별 | ||||||||||
| 강남구 | 516.0 | 39.0 | 5.0 | 3587.0 | 4002.0 | 80.038760 | 100.000000 | 100.000000 | 53.470867 | 88.130935 |
| 강동구 | 160.0 | 14.0 | 4.0 | 1754.0 | 2530.0 | 95.000000 | 92.857143 | 100.000000 | 51.425314 | 86.996047 |
| 강북구 | 217.0 | 5.0 | 7.0 | 1222.0 | 2778.0 | 73.271889 | 80.000000 | 85.714286 | 54.991817 | 89.344852 |
| 관악구 | 322.0 | 12.0 | 6.0 | 2103.0 | 3235.0 | 81.987578 | 83.333333 | 100.000000 | 44.555397 | 83.678516 |
| 광진구 | 279.0 | 11.0 | 4.0 | 2636.0 | 2392.0 | 83.870968 | 54.545455 | 100.000000 | 40.098634 | 84.071906 |