PYTHON LIBRARY/Project 연습 (새로운 개념 정리 추가!)

프로젝트(범죄현황) 연습(2) : Pandas pivot_table 익혀서 범죄 데이터에 적용 및 데이터 시각화

신강희 2024. 5. 3. 11:59
728x90

< pandas의 pivot_table 익히기 >

- 바로 이전 프로젝트 연습예제문을 이어서 진행

 

# 구이름을 인덱스로 만들려는데
# 인덱스는 유니크해야 하므로 구이름이 중복된 값은 모든 데이터 값을 합친다
# 그러기 위한 방법이 pivot_table ( 데이터프레임의 데이터를 피벗하여 요약하는 데 사용)

 

import pandas as pd
import numpy as np

 

# 피봇팅 한다. 즉 컬럼의 값을 인덱스로 만들되, 
# 인덱스를 중복제거하여 유니크 하게 만드는 방법

# 새로운 데이터로 코딩 한다.

 

df_test = pd.read_excel('../data/sales-funnel.xlsx')

df_test

 

# Name 열을 가지고 하나로 합쳐서 인덱스로 만들고 싶을때
#기본적으로 동일한 데이터를 합칠때, 숫자 데이터를 default 평균으로 출력한다

 

pd.pivot_table(df_test, index= ['Name'], values = ['Quantity' , 'Price'])

 

#숫자 데이터를 합하여 출력하고 싶다
pd.pivot_table(df_test, index= ['Name'], values = ['Quantity' , 'Price'], aggfunc= 'sum')

 

# Prodeuct 를 인덱스로 하고 price의 최대값을 보자
pd.pivot_table(data= df_test, index= ['Product' , 'Rep'], values = ['Price'], aggfunc=['max','min'])

 

# 이제 피벗테이블을 이전에 실습하던 범죄데이터에 적용해 보자.

# 범죄 데이터 구별로 정리하기

# 피봇으로 합칠때 문자열은 합치는게 불가능 하다. 그러므로 문자열인 관서명은 삭제한다
crime_anal = df.drop('관서명', axis=1)
crime_anal

 

# 구별로 모든 범죄 데이터의 합 => 만약의 함수를 하나만 쓸거면 aggfunc= 뒤에 [] 를 지워도 되고, 여러 함수를 쓸거면 [] 안에 적어야함
crime_anal = pd.pivot_table(data= crime_anal, index=['구이름'], aggfunc='sum')

crime_anal

 

실습 4) 인덱스를 '구별' 로 피봇팅 한다.

crime_anal.reset_index(inplace=True)

crime_anal.rename(columns={'구이름' : '구별'}, inplace=True)

crime_anal

 

crime_anal = pd.merge(df_cctv, crime_anal, on='구별')

crime_anal

ㄴ 데이터 24행 까지 있음

 

실습 5) '강간검거율' , '강도검거율', '살인검거율', '절도검거율', '폭력검거율' 을 계산하여, 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

crime_anal['폭력검거율'] = crime_anal['폭력 검거'] / crime_anal['폭력 발생'] * 100

 

crime_anal

 

실습 6) 이제 필요없는, '강간 검거' , '강도 검거', '살인 검거', '절도 검거', '폭력 검거' 컬럼을 제거한다.

crime_anal = crime_anal.drop(['강간 검거','강도 검거','살인 검거','절도 검거','폭력 검거'], axis=1)

crime_anal

 

실습 7) describe() 함수로 값을 확인해 보니, 검거율이 100 이상인 경우도 있다. 따라서 100보다 크면, 100으로 값을 셋팅하세요.

crime_anal.describe()

ㄴ 작년에 발생된 범죄를 올해 검거할수도 있고, 발생시기와 검거시기가 달라서 데이터에 오류가 생긴것

ㄴ 이렇기 때문에 데이터 가공 중간중간 검토가 필수

 

crime_anal.loc[crime_anal['강간검거율'] >= 100 , '강간검거율' ] = 100

crime_anal.loc[crime_anal['강도검거율'] >= 100 , '강도검거율' ] = 100

crime_anal.loc[crime_anal['살인검거율'] >= 100 , '살인검거율' ] = 100

 

crime_anal.describe()

 

실습 8) 강간 발생, 강도 발생, 살인 발생, 절도 발생, 폭력 발생 의 컬럼 명을, 강간, 강도, 살인, 절도, 폭력으로 rename 하세요.

crime_anal.rename( columns= { '강간 발생' : '강간' , '강도 발생' : '강도', '살인 발생' : '살인', '절도 발생' : '절도', '폭력 발생' : '폭력' }, inplace=True)

 

실습 9) 강간, 강도, 살인, 절도, 폭력 을 피처스케일링 중 노멀라이징 합니다.

데이터 노멀라이징 하는 이유는, 각각의 레인지를 통일하여, 해석하기 쉽게 하기 위함입니다.

 

# 파이썬에서 머신러닝 관련된 라이브러리 sklearn
from sklearn.preprocessing import StandardScaler, MinMaxScaler

 

# 표준화와 정규화 를 통해 피처스케일링
# 데이터와 데이터간의 범위를 맞춰주기 위해서 시행하는 방법 다만, 머신러닝을 시키기위해서 해당 두가지 방법으로 시행한다.
# 중요한것은 컬럼과 컬럼간에 데이터들을 비교하는것! 이걸 위해서 피처스케일링이 필요하다.

 

# 라이브러리를 우선 변수로 만들어줘야 한다. 메모리에 업로드
# (1) 표준화
s_scaler = StandardScaler()

 

# 피처스케일링 => .fit_transform()
s_scaler.fit_transform( crime_anal.loc[ : , '강간' : '폭력'] )

array([[ 2.73165666,  2.28990327,  1.88244875,  2.65339664,  2.71104172],
       [-0.73257205, -1.15874623, -0.7320634 ,  0.24905364,  0.16786275],
       [-0.76804197,  0.6805335 ,  0.13944065, -1.26095153,  0.06594146],
       [ 0.5206984 ,  0.45062353,  0.13944065, -0.18839421,  0.96867292],
       [ 1.20645016,  0.22071357,  0.72044335,  0.7999139 ,  1.11589257],
       [ 0.26058567,  0.6805335 , -0.7320634 ,  1.31837061,  0.0271143 ],
       [ 0.74534122,  0.91044347,  0.429942  ,  0.19882815,  0.64511326],
       [-0.79168858, -1.15874623, -1.02256475, -1.04546796, -0.89664854],
       [-0.2478165 , -0.92883626,  1.0109447 , -0.03123702,  0.18565854],
       [-1.37103059, -0.46901633, -1.02256475, -1.86203728, -1.81394019],
       [-0.53157585,  0.45062353, -0.44156205, -0.37471459, -0.09745617],
       [ 0.79263445, -0.46901633, -0.44156205, -0.56265515, -1.1296115 ],
       [ 0.8990442 ,  0.6805335 ,  0.429942  ,  0.55526714,  0.6062861 ],
       [-0.75621866, -1.3886562 , -1.3130661 , -0.64852454, -0.89341295],
       [ 2.06955151, -0.46901633,  0.429942  ,  0.68488131, -0.33850812],
       [-1.08727124, -0.46901633, -0.7320634 , -0.98066087, -1.6117154 ],
       [-0.80351189, -1.3886562 , -0.44156205, -0.69226932, -0.6458898 ],
       [ 0.02411954,  0.45062353,  1.30144605,  1.66346836,  1.11103918],
       [-1.15821107, -1.15874623, -1.02256475, -0.52215071, -0.16055031],
       [ 0.91086751,  2.51981323,  2.1729501 ,  1.21791962,  1.55916931],
       [-0.28328642,  0.6805335 , -0.44156205, -1.06166973, -0.90311974],
       [-0.61433899, -0.46901633, -1.02256475, -0.48326646,  0.07241265],
       [-0.08229021, -0.0091964 , -0.1510607 , -0.04581861, -0.50999474],
       [-0.56704576, -0.46901633, -1.02256475,  0.5439259 , -0.62162283],
       [-0.36604956, -0.0091964 ,  1.88244875, -0.1252073 ,  0.38626553]])

ㄴ 머신러닝 라이브러리로 실행하였기 때문에 결과는 numpy로 출력된다. 머신러닝은 numpy로 동작

 

# (2) 정규화
m_scaler = MinMaxScaler()

m_scaler.fit_transform( crime_anal.loc [ : , '강간' : '폭력' ] )

array([[1.        , 0.94117647, 0.91666667, 1.        , 1.        ],
       [0.1556196 , 0.05882353, 0.16666667, 0.46752781, 0.43796925],
       [0.14697406, 0.52941176, 0.41666667, 0.13311805, 0.41544512],
       [0.4610951 , 0.47058824, 0.41666667, 0.37064944, 0.61494458],
       [0.62824207, 0.41176471, 0.58333333, 0.58952278, 0.64747944],
       [0.39769452, 0.52941176, 0.16666667, 0.70434159, 0.4068645 ],
       [0.51585014, 0.58823529, 0.5       , 0.45640474, 0.5434394 ],
       [0.14121037, 0.05882353, 0.08333333, 0.18083961, 0.2027172 ],
       [0.27377522, 0.11764706, 0.66666667, 0.40545389, 0.44190204],
       [0.        , 0.23529412, 0.08333333, 0.        , 0.        ],
       [0.20461095, 0.47058824, 0.25      , 0.32938644, 0.379335  ],
       [0.52737752, 0.23529412, 0.25      , 0.28776462, 0.15123346],
       [0.55331412, 0.52941176, 0.5       , 0.53534266, 0.53485878],
       [0.14985591, 0.        , 0.        , 0.26874776, 0.20343225],
       [0.83861671, 0.23529412, 0.5       , 0.56404736, 0.32606364],
       [0.06916427, 0.23529412, 0.16666667, 0.19519196, 0.04469074],
       [0.13832853, 0.        , 0.25      , 0.25905992, 0.25813371],
       [0.34005764, 0.47058824, 0.75      , 0.78076785, 0.64640686],
       [0.0518732 , 0.05882353, 0.08333333, 0.29673484, 0.36539149],
       [0.55619597, 1.        , 1.        , 0.68209544, 0.74544154],
       [0.26512968, 0.52941176, 0.25      , 0.17725152, 0.20128709],
       [0.18443804, 0.23529412, 0.08333333, 0.30534625, 0.41687522],
       [0.31412104, 0.35294118, 0.33333333, 0.40222461, 0.28816589],
       [0.19596542, 0.23529412, 0.08333333, 0.532831  , 0.2634966 ],
       [0.24495677, 0.35294118, 0.91666667, 0.38464299, 0.48623525]])

 

# 이번 예제문에선 정규화한 값을 사용 // 정규화한 값을 데이터에 넣어준다.

 

crime_anal.loc[:,'강간':'폭력'] = m_scaler.fit_transform( crime_anal.loc[:,'강간':'폭력'])

 

실습 10) 강간, 강도, 살인, 절도, 폭력 의 값을 모두 더하고, 이 더한값을 '범죄' 라는 컬럼을 만들어서 넣습니다.

crime_anal.columns

Index(['구별', '소계', '최근증가율', '인구수', '한국인', '외국인', '고령자', '외국인비율', '고령자비율', '강간',
       '강도', '살인', '절도', '폭력', '강간검거율', '강도검거율', '살인검거율', '폭력검거율', '절도검거율'],
      dtype='object')

 

# 분석에 필요없는 컬럼은 제거해 주자.

crime_anal.drop(['최근증가율', '인구수', '한국인', '외국인', '고령자'] , axis=1, inplace=True)

 

# 소계 컬럼은 CCTV의 수를 나타내는 것이므로 알아보기 쉽게 컬럼명 변경

crime_anal.rename(columns={'소계' : 'CCTV'}, inplace=True)

 

# 인덱스를 '구별'로 설정하여 저장

crime_anal.set_index('구별', inplace=True)

 

# 기본 가공이 끝났으니 문제 예제 실행
crime_anal['범죄'] = crime_anal['강간'] + crime_anal['강도'] + crime_anal['살인'] + crime_anal['절도'] + crime_anal['폭력']

 

crime_anal

 

실습 11) '강간검거율','강도검거율','살인검거율','절도검거율','폭력검거율' 의 값을 모두 더하고, 이 더한값을 '검거' 라는 컬럼을 만들어서 넣습니다.

crime_anal['검거'] = crime_anal['강간검거율'] + crime_anal['강도검거율'] + crime_anal['살인검거율'] + crime_anal['절도검거율'] + crime_anal['폭력검거율']

 

crime_anal

 

< Visualization using seaborn >

실습 12) sb의 pairplot 으로 "강도", "살인", "폭력" 을 나타내세요. (연관성 확인)

 

crime_anal[['강도','살인','폭력']].corr()

 

# 시각화 해보자

import matplotlib.pyplot as plt
import seaborn as sb

 

# 3개 컬럼을 넣을경우 (1,3) (2,3) (1,3) 관계를 다 보여줌

sb.pairplot(data= crime_anal, vars= ['강도' , '살인', '폭력'])
plt.show()

 

실습 13) x_vars는 "인구수", "CCTV" 를, y_vars는 "살인", "강도"로 pariplot을 나타내고, 연관성을 확인하세요.

sb.pairplot(data=crime_anal, x_vars= ["인구수", "CCTV"], y_vars=[ "살인", "강도","강간"])
plt.show()

 

# 해당 그래프 만으로는 관계성을 알아보기 어렵기 때문에 상관계수가 필요한것

crime_anal[['인구수','CCTV','살인','강도','강간']].corr()

 

실습 14. x_vars는 "인구수", "CCTV" 를, y_vars는 "살인검거율", "폭력검거율"로 pariplot을 나타내고, 연관성을 확인하세요.

# pairplot 에도 regplot 처럼 선을 나타내는 방법이 있다. kind = 'reg' 를 입력
sb.pairplot(data=crime_anal, x_vars= ["인구수", "CCTV"], y_vars=[ "살인검거율", "폭력검거율","절도검거율"] , kind='reg')
plt.show()

 

crime_anal[['인구수','CCTV','살인검거율','폭력검거율','절도검거율']].corr()

 

실습 15) 검거가 가장 높은 구는 어디입니까? 이를 확인하기 위해, 검거가 가장 높은 구부터 정렬하여 5개의 구까지 나타내세요.

crime_anal.sort_values('검거', ascending=False).head()

 

실습 16) 검거가 가장 큰값이 432.593167 입니다. 검거의 값이 최대가 100이 되도록 정규화를 하세요. 그리고 검거값으로 정렬하세요.

catch = (crime_anal['검거'] - crime_anal['검거'].min()) / (crime_anal['검거'].max() - crime_anal['검거'].min()) * 100

crime_anal.loc[ : , '검거'] = catch

crime_anal.sort_values('검거', ascending=False).head()

 

# 강사님 풀이

crime_anal['검거'] = crime_anal['검거'] / crime_anal['검거'].max() * 100

crime_anal.sort_values('검거' ,ascending=False).head()

 

실습 17) sb.heatmap 을 이용해서 '강간검거율', '강도검거율', '살인검거율', '절도검거율', '폭력검거율' 을 보여주세요. 단, '검거' 로 정렬한 데이터로 보여주세요.

# 데이터프레임에 value 부분의 숫자를 색으로 표시하고 싶을때
# sb.heatmap 함수를 사용한다. // plt.hist2d 랑은 다르다. hist2d는 두컬럼간의 관계를 나타내는것 => 상황마다 사용하는것이 다르니 외워둘것

 

# 검거로 정렬하라고 하였으니 검거 정렬값을 변수로 지정
df5 = crime_anal.sort_values('검거' ,ascending=False)

 

# 실제 차트로 그릴 데이터를 가져와서 변수로 지정
df6 = df5.loc [ : , '강간검거율' : '절도검거율' ]

 

df6

 

# 이제 해당 데이터를 색으로 표시하자
# sb.heatmap( data , camp= '색깔', annot=True (숫자로 표시) , fmt=' .1f' (숫자 형식 지정), linewidths=0.8 (칸들간에 거리)
# figure. figsize는 차트 크기 (행 열 크기 지정)
plt.figure(figsize=(10,8))
sb.heatmap(data=df6, cmap='RdPu', annot=True, fmt=' .1f', linewidths=0.8)
plt.show()

 

실습 18) 위에서 배운 히트맵을 이용해서, 살기 무서운 구가 어디인지 분석하세요.

# 범죄율이 가장 높은 구가 살기 무서운구일것이니 범죄로 정렬해보자
# 정렬 기준은 '범죄' 차트로 그릴 데이터는 강간~폭력 발생율
df7 = crime_anal.sort_values('범죄', ascending=False).loc[ :  , '강간' : '폭력' ]
df7

 

plt.figure(figsize=(10,8))
sb.heatmap(data=df7, cmap='RdPu', annot=True, fmt=' .1f', linewidths=0.8)
plt.show()

 

프로젝트 범죄데이터 실습 종료

반응형