EDA - 02. Analysis Seoul Crime_part [1] (w. Pandas pivot, Seaborn)

jaam._.mini·2023년 12월 3일
0




데이터 개요


thousands=","

숫자로 인식시켜주기 위해 쓰는 코드

import numpy as np
import pandas as pd
crime_raw_data = pd.read_csv("../data/02. crime_in_Seoul.csv", thousands=",", encoding="euc-kr")
crime_raw_data.head()

info()

데이터의 개요 확인하기

crime_raw_data.info()

.unique() 컬럼 확인

죄종이 어떤 것들이 있는지 확인

crime_raw_data["죄종"].unique()

isnull()

불리언 타입으로 얼마나 있는지 나옴

crime_raw_data["죄종"].isnull()

데이터 마스킹 = 표 형태

마스킹 해주면 데이터 프레임 형태(표)로 나옴

crime_raw_data[crime_raw_data["죄종"].isnull()]

notnull

nan이 아닌 타입들이 얼만큼 있는지 알려


crime_raw_data[crime_raw_data["죄종"].notnull()]

notnull 만 rawdata로 지칭

crime_raw_data = crime_raw_data[crime_raw_data["죄종"].notnull()]
crime_raw_data.info()






Pandas pivot table


  • 종류 : index, columns, values, aggfunc

설치

!conda install -y openpyxl
import numpy as np
import pandas as pd

데이터 불러오기

df = pd.read_excel("../data/02. sales-funnel.xlsx")
df.head()



index 설정 (with Value)

  • name 컬럼을 인덱스로 설정하고자 한다
df.pivot_table(index='Name', values=['Account', 'Quantity', 'Price'])

(어떤 데이터를 사용할지-데이터프레임 넣기, 어떤 컬럼을 인덱스로 지정할지 컬럼 이름)


멀티 index

df.pivot_table(index=['Name', 'Rep', 'Manager'], values=['Account', 'Quantity', 'Price'])


values 설정

value 값에 연산된 값을 넣기

price 컬럼, sum 연산 적용

(인덱스 값, 밸류 값, 기능 추가:합계)

df.pivot_table(index=['Manager', 'Rep'], values='Price', aggfunc=np.sum)


aggfunc 2개 이상 설정

★ 2개 이상일 때에는 list[]로 감싸줘야 한다 ★

df.pivot_table(index=['Manager', 'Rep'], values='Price', aggfunc=[np.sum, len])


columns 설정

# Product를 컬럼으로 지정

df.pivot_table(index=['Manager', 'Rep'], values='Price', columns='Product', aggfunc=np.sum)


fill_value=0

NaN 값이 있다면 0으로 채워라

df.pivot_table(index=['Manager', 'Rep'], values='Price', columns='Product', aggfunc=np.sum, fill_value=0)

# 2개 이상 index, values 설정

df.pivot_table(index=['Manager', 'Rep', 'Product'], values=['Price','Quantity'], aggfunc=np.sum, fill_value=0)


aggfunc 2개 이상 설정

aggfunc=[np.sum, np.mean] : 더하기, 평균

df.pivot_table(
    index=['Manager', 'Rep', 'Product'], 
    values=['Price','Quantity'], 
    aggfunc=[np.sum, np.mean], 
    fill_value=0,
    margins=True # 전체 총계(All)가 추가 됨
)






데이터 정리

Pandas pivot table


pivot table을 만들고자 함

crime_station에 crime_raw_data를 적용
(crime_raw_data를 raw data로 담아주고, 인덱스를 설정, 컬럼 설정, 연산기능 추가)

crime_station = crime_raw_data.pivot_table(crime_raw_data, index='구분', columns=['죄종','발생검거'], aggfunc=[np.sum])
crime_station.head()


columns 확인

어떤 컬럼의 항목들이 있는지 확인 후 삭제/원하는 값만 추출하고자 함

crime_station.columns # MultiIndex 가 있는 걸 확인!


MultiIndex >> index

crime_station에서 [보고싶은 항목들 입력][ 5개만 보고싶음 ]

crime_station['sum','건수','강도', '검거'][:5]


droplevel()

  • 다중 컬럼 >> 특정 컬럼을 삭제하는 방법

44번 줄에서 날리고 싶은 인덱스를 정수(인티저)형태로 넣어준다

데이터.컬럼 = 데이터.컬럼.삭제명령([날리고 싶은 인덱스])

crime_station.columns = crime_station.columns.droplevel([0,1])

crime_station.head()

인덱스 확인

crime_station.index






Python 모듈 설치

구글 API 설치


pip 명령

  • Python의 공식 모듈 관리자

  • pip list : 현재 설치된 모듈 리스트 변환

  • pip install module_name : 모듈 설치

  • pip uninstall module)name : 설치된 모듈 제거

!pip list
# get_ipython().system('pip list')



conda 명령

  • pip를 사용하면 conda 환경에서 dependency관리가 정확하지 않을 수 있다.

  • 아나콘다에서는 가급적 conda 명령으로 모듈을 관리하는 것이 좋다

  • conda list : 설치된 모듈 list

  • conda install module_name : 모듈 설치

  • conda uninstall module_name : 모듈 제거

  • conda install -c channel_name module_name : 지정된 배포 채널에서 모듈 설치



Google Maps API 설치






Python반복문


간단한 for()

for n in [1,2,3,4]:
    print("Number is", n)

복잡한 for()

for n in range(1,10):
    print(n**2)

한줄 반복문

[n**2 for n in range(1,10)]

Pandas에서 잘 맞춰진 반복문용 명령 iterrows()

  • Pandas 데이터 프레임은 대부분 2차원
  • 이럴 때 for문을 사용하면 n번째 하는 지정을 반복해서 가독률이 떨어짐
  • Pandas 데이터 프레임으로 반복문을 만들때 itterows() 옵션을 사용하면 편함
  • 받을 때, 인덱스와 내용으로 나누어 받는 것만 주의






데이터 [정리]


import googlemaps

● 중요하게 볼 항목
'formatted_address': '대한민국 서울특별시 영등포구',
'geometry': {'bounds': {'northeast': {'lat': 37.556286, 'lng': 126.9498867},

변수에 담기

# 중요하게 볼 항목의 추출을 위해 tmp 라는 변수에 넣어 줌

tmp = gmaps.geocode('서울영등포경찰서', language='ko')
tmp

데이터 수 확인

len(tmp)

항목 접근 방법

#위에 길이가 1개니까, [0]에 접근해서 
#get을 통해 geometry 항목에 접근

tmp[0].get('geometry')

key 접근 방법

#get을 통해 geometry 항목에 접근, key 값(location)에 접근

tmp[0].get('geometry')['location']

특정 index 값 확인

print(tmp[0].get('geometry')['location']['lat'])
print(tmp[0].get('geometry')['location']['lng'])

특정 index 값 확인

tmp[0].get('formatted_address')

split()

띄어쓰기로 나눠져 있는 걸, list형태의 객체로 바꿔줌

# .split() : 띄어쓰기로 나눠져 있는 걸, list형태의 객체로 바꿔줌

tmp[0].get('formatted_address').split()

특정 데이터 반환

# 우리가 필요한 '영등포구'만 반환이 필요

tmp[0].get('formatted_address').split()[2]

출력/확인

crime_station.head()


좌표(내용) 추가

# 컬럼을 추가, 추가한 값은 nan으로 전부 채워 줌

crime_station['구별'] = np.nan
crime_station['lat'] = np.nan
crime_station['lng'] = np.nan
crime_station.head()


반복문(iterrows) : NaN채우기

▼ 반복문(iterrows)을 이용해서 NaN 값을 채움

  • 경찰서 이름에 소속된 구 이름 얻었음
  • 구 이름과 위도, 경도 정보를 저장할 준비 완료

반복문(iterrows) 형태

for idx, rows in 파일명.iterrows():

  • station_name 변수 지정을 통해 지역별 경찰서 이름을 만들어 줌
  • str로 분자로 변환 꼮! 해줘야 함
count = 0

for idx, rows in crime_station.iterrows():
    station_name = "서울" + str(idx) + "경찰서"
    tmp = gmaps.geocode(station_name, language="ko")
    
    if tmp:
        tmp[0].get("formatted_address")
        tmp_gu = tmp[0].get("formatted_address")
        
        lat = tmp[0].get("geometry")["location"]["lat"]
        lng = tmp[0].get("geometry")["location"]["lng"]
        
        crime_station.loc[idx, "lat"] = lat
        crime_station.loc[idx, 'lng'] = lng
        crime_station.loc[idx, '구별'] = tmp_gu.split()[2]

        print(count)
        count = count +1

# 서울 동작 경찰서의 경우 geocode에서 검색 결과가 나오지 않아 tmp가 빈 리스트로 나오기 때문에 생기는 문제
# 강의 제작 시에는 서울 동작 경찰서도 geocode에서 출력이 잘 나왔지만, 현재는 구글쪽 검색 결과가 달라짐에 따라 
# if tmp: 를 추가해 찾지 못한 경우 입력하지 않도록 동작 명령
crime_station.head()


개별 접근 : get_level_value(0)[2]

개별적 접근이 가능

  • crime_station 에서 컬럼에 접근.하나씩 접근
crime_station.columns.get_level_values(0)[2] + crime_station.columns.get_level_values(1)[2]
len(crime_station.columns.get_level_values(0))

리스트 컴프리헨션(초기화)

# 리스트 컴프리헨션(List Comprehension) : for 문을 한 줄로 요약하는 것

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


마무리 : 변수 담기 / 저장






데이터 [변경]


파일 불러오기

# 저번에 저장한 파일 불러오기
# 단,  index_col=0, encoding='utf-8' : 0번 구분 인덱스를 기준으로, 한글파일로 읽어 옴

crime_anal_station = pd.read_csv('../data/02. crime_in_Seoul_raw.csv', index_col=0, encoding='utf-8')
crime_anal_station.head()

특정 컬럼 삭제

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()


컬럼 나누기(.div)

하나 / 하나


crime_anal_gu['강도검거'] / crime_anal_gu['강도발생'] 

다수 / 한개

# 다수의 컬럼을 다른 컬럼으로 나누기
crime_anal_gu[['강도검거', '살인검거']].div(crime_anal_gu['강도발생'], axis=0).head(3)

다수 / 다수

# 다수 / 다수

#리스트로 먼저 만들어 준다
num = ['강간검거','강도검거','살인검거','절도검거','폭력검거'] #분자
den = ['강간발생','강도발생','살인발생','절도발생','폭력발생'] #분모

crime_anal_gu[num].div(crime_anal_gu[den].values).head()


컬럼(데이터) 생성/추가

# target 컬럼 생성

target = ['강간검거율','강도검거율','살인검거율','절도검거율','폭력검거율']

num = ['강간검거','강도검거','살인검거','절도검거','폭력검거']
den = ['강간발생','강도발생','살인발생','절도발생','폭력발생']

crime_anal_gu[target] = crime_anal_gu[num].div(crime_anal_gu[den].values) * 100
crime_anal_gu.head()

100으로 수치(데이터) 맞추기

crime_anal_gu[crime_anal_gu[target] > 100] = 100
crime_anal_gu.head()

삭제

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

.rename()

컬럼 이름 변경

# 컬럼 이름 변경 : .rename()

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






데이터 [정렬]


불러오기

crime_anal_gu.head()

정규화 (최대 1, 최소 0)

# 정규화 : 최고값은 1, 최소값은 0
#col : 첫 번째 컬럼

col= ['강간','강도','살인','절도','폭력']
crime_anal_norm = crime_anal_gu[col] / crime_anal_gu[col].max()
crime_anal_norm.head()

컬럼 추가

# 검거율 데이터도 위 도표에 추가하고자 함
#col2 : 두번째 컬럼

col2 = ['강간검거율','강도검거율','살인검거율','절도검거율','폭력검거율']
crime_anal_norm[col2] = crime_anal_gu[col2]
crime_anal_norm.head()

데이터 불러오기

# 인구수와 cctv수 추가를 위해 과거 자료 불러오기

result_CCTV = pd.read_csv("../data/01. CCTV_result.csv", index_col='구별', encoding='utf-8')
result_CCTV.head(1)

컬럼/데이터 추가

# 자료 추가

crime_anal_norm[['인구수','CCTV']] = result_CCTV[['인구수','소계']]
crime_anal_norm.head()

평균 컬럼/데이터 추가

# 정규화된 범죄발생 
# 건수전체의 평균을 구해서 범죄 대표값으로 사용

col= ['강간','강도','살인','절도','폭력']

crime_anal_norm['범죄'] = np.mean(crime_anal_norm[col], axis=1)
crime_anal_norm.head()
col = ['강간검거율','강도검거율','살인검거율','절도검거율','폭력검거율']
crime_anal_norm['검거'] = np.mean(crime_anal_norm[col], axis=1)
crime_anal_norm.head()

최종, 출력

crime_anal_norm






제로베이스 데이터 스쿨
profile
비전공자의 데이터 공부법

0개의 댓글