6주차
수강한 분량
EDA, 웹크롤링, 파이썬 프로그래밍의 일부분인 OT, 서울시 CCTV 현황 데이터 분석, 서울시 범죄 현황 데이터 분석
각 강의별 학습한 핵심 내용 정리
EDA / 웹크롤링 / 파이썬 프로그래밍
OT
프로젝트 위주로 진행하여, 잦은 변화 속 중요한 흐름을 이해하고 다양한 경험을 하는 것을 목표로 한다
minoconda 설치
- win
- anaconda Prompt
- mac
- homebrew 설치 필요
- M1
- miniforge설치
conda 가상환경
-
버전 확인
- conda --version
-
업데이트하기
- conda update conda
-
conda 가상환경 생성
- conda create -n ds_study python=3.8
-
conda 가상환경 활성화
- conda activate ds_study
-
conda 가상환경 비활성화
- conda deactivate
-
conda 가상환경 목록
- conda env list
-
conda 가상환경 삭제
- conda env remove -n ds_study
-
jupyter notebook 설치
- conda install jupyter
-
package 설치
- conda install ipython
- conda install matplotlib
- conda install seaborn
- conda install pandas
- conda install scikit-learn
- conda install xlrd
-
jupyter notebook 실행
- jupyter notebook~~
-
matplotlib 한글 설정(일단매번 설정해둠)
import matplotlib.pyplot as plt
from matplotlib import rc
%matplotlib inline
rc('font', family = 'Malgun Gothic')
from matplotlib import font_manager
f_path = 'C:\Windows\Fonts\malgun.ttf'
font_manager.FontProperties(fname-f_path).get_name()
vscode 환경설정
- ctrl + shift + p
- select interpreter
- python: select interpreter
- ds_study 있는것 선택
서울시 CCTV 현황 데이터 분석
목표
- 서울시 구별 CCTV 현황 데이터 확보
- 인구 현황 데이터 확보
- CCTV 데이터와 인구 현황 데이터 합치기
- 데이터 정리, 정렬
- 그래프 그리기
- 전체 경향 파악하는 능력
- 경향에서 벗어난 데이터 강조하는 능력
1~4: python, pandas
5: matplotlib
6: regression using numpy
7: insight, visualization
엑셀, 텍스트 파일 읽기
data = pd.read_csv("파일주소/파일명.확장자", encoding = 'utf-8')
- 인코딩값은 변하기도 함
data.head()
- 정렬된 값 중 상위 5개를 보는 것
- ()안에 숫자를 넣으면 그만큼 볼 수 있음
data.tail()
- 정렬된 값 중 하위 5개를 보는 것
- ()안에 숫자를 넣으면 그만큼 볼 수 있음
data.columns
- 컬럼 이름 조회
data.rename(columns = {"원래이름" : "바꿀이름" }, inplace = True)
- 원래이름 자리에 data.columns[n]으로 표시하는 것이 편하기도 하다
- inplace = True 옵션
- 원본 데이터를 이번 버전으로 교체하는 여부
- True / False
data = pd.read_excel("파일주소/파일명.확장자")
- 엑셀 파일을 여는 함수
data = pd.read_excel("파일주소/파일명.확장자", header = n, usecols = "Alphabets")
- 헤더에 병합셀이 있을 수 있으므로 헤더를 지정해주는 것이 좋다
- header 옵션
- 자료를 읽기 시작할 행
- usercols 옵션
- Alphabets는 읽어올 엑셀의 지정 컬럼
python 모듈 규칙
import MODULE
- module을 사용하겠다
- MODULE.function
import MODULE as md
- module을 사용할 건데 md라고 부르겠다
- md.function
from MODULE import function
- module에 포함된 function 함수만 사용하겠다
- function
pandas 이용하기
Series
- pandas의 데이터형의 기본 구성
- index, value로 이루어져 있다.
- DF의 컬럼 한 줄 한 줄은 Series로, 이것들이 모여 DF가 된다.
- 한 가지 데이터 타입만 가질 수 있다.
- 입력 데이터타입이 단일하지 않을 때 전체를 문자열, 실수형 데이터로 인식하게 됨
date_range("시작날짜", periods = n)
- 시작날짜부터 n일까지의 날짜 목록을 만드는 함수
- 시작날짜 양식은
- 예시: 20240429
- 데이터 타입
- datetime64
DataFrame
- DataFrame 선언 방법
- pd.DataFrame(값, index = 값, columns = [값])
- index와 columns를 지정해야한다
- pd.DataFrame({"Key": ["K0", "K1"], "A": ["A0", "A1"]})
- 열 단위로 지정
- pd.DataFrame({"Key": "K0", "A": "A0"}, {"Key": "K1", "A": "A1"})
- 행 단위로 지정
- 각 값만 보고 싶을 때
- df.index
- df.columns
- df.values
df.info()
- df 기본 정보 확인
- 각 컬럼 크기와 데이터 형태 확인하는 용도
df.describe()
- df의 통계적 기본 정보 확인용
df.sort_values(by = "컬럼명", ascending = False)
- by 옵션
- 컬럼명 기준으로 정렬
- ascending 옵션
- True일 경우 오름차순
df["컬럼명"]
- 특정 컬럼만 읽기
- 컬럼명이 문자열인 경우 df.컬럼명
으로도 가능하다
df[인덱스 범위1:인덱스 범위2]
- 인덱스 범위에 있는 데이터 확인
- 인덱스 범위를 숫자로 지정할 경우 인덱스 범위2에서 1개 뺀 값
- 인덱스 범위를 이름으로 지정할 경우 끝까지 포함
df.loc[행, 열]
- :
표현
- 전체 선택
- [, ]
표현
- 일부 선택
df.iloc[행, 열]
- 열 생략시 행만 선택
- :
구분자를 이용해 범위를 지정하여 슬라이싱
- []
을 이용해 띄어서 선택도 가능
df[df["A"] > 0]
- df의 A컬럼 값 중 0보다 큰 것들만 선택적으로 보여준다
- 내부는 조건문
- 이때 전체 df 모양은 살린다
- 조건에 맞지 않는 부분은 NaN으로 표시된다
- NaN: Not a Number
df["E"] = [값들]
- 새로운 컬럼 E를 만들어 값들을 넣어준다.
df["E"].isin([값들])
- df의 E 컬럼에 값들이 있는가, 그렇다면 True, 아니면 False 반환
- 조건문이므로 저것을 활용한 df만 편집하여 볼 수 있다
del df["컬럼명"]
- 특정 컬럼 삭제하기
df.drop([입력값], axis = 1)
- axis 옵션
- 0
- 디폴트값
- 인덱스를 기준으로 삭제
- 1
- 컬럼을 기준으로 삭제
df.apply(함수)
- 함수를 각 컬럼마다 적용한 결과를 확인할 수 있다
- 예시) df.apply(np.cumsum)
- 각 컬럼 누적합
df.set_index("컬럼명", inplace = True)
- index를 재지정하는 함수
- unique한 데이터를 index로 잡는 것이 좋음
df.corr()
- 데이터 상관관계 찾는 함수
- 최소한의 근거가 있어야 해당 데이터를 비교하는 의미가 존재
- 0.2 이상 데이터 비교하는 것은 의미 있다
- 상관관계 != 인과관계
- 두 데이터 합치기
- pandas.merge() 함수를 이용하여 병합
- pd.merge(left, right, on = 'key')
- key 컬럼을 기준으로 병합
- pd.merge(left, right, how = 'left', on = 'key')
- left에 key 를 기준으로 right 병합
- right에 없는 값은 NaN으로 표시된다
- left key에 없는 값은 없어진다
- pd.merge(left, right, how = 'outer', on = 'key')
- 둘 다 손상되지 않도록 key 컬럼을 기준으로 병합
- 각자 없는 값은 NaN으로 표시된다
- pd.merge(left, right, how = 'inner', on = 'key')
- key 컬럼에서 두 데이터에 공통 분모만 병합
- 기본 디폴트값
- pandas.concat() 함수를 이용하여 병합
- pandas.join() 함수를 이용하여 병합
df.to_csv("경로/파일이름.csv", sep = ",", encoding = "utf-8")
- DataFrame을 csv로 저장하는 함수\
matplotlib 기초
- 그래프 결과가 중요할 경우 그래프 그리는 코드를 def()로 작성한다. 별도의 셀에서 그림만 나타낼 수 있기 때문이다
import matplotlib as mpl
- 자주 사용은 않지만 자주 쓰는 약어 알아두기
import matplotlib.pyplot as plt
- 2차원 그래프 그리는 모듈
- matlab에 있는 기능을 담아둔 곳
from matplotlib.colors import ListedColormap
- 사용자 정의로 color map을 세팅할 수 있는 함수
- ListedColormap(리스트값)
을 이용해 나만의 color map을 생성
get_ipython().run_line_magic('matplotlib', 'inline')
- 주피터 노트북에서 matplotlib 결과를 문서에 포함시켜서 출력하라
- %matplotlib inline
이라고 작성해도 무방
plt.figure(figsize = (n, m))
- 가로 n 세로 m 길이의 사이즈의 그래프를 그려라
- figure 하나에 여러 그래프를 그릴 수 있다
- nXm 크기의 도화지를 설정한다고 생각하기
plt.plot(x 데이터, y 데이터, label = '라벨값', "선스타일옵션")
- x 데이터에 대응되는 y 데이터를 라벨값을 라벨로 달아서 그려라
- 선 스타일 옵션, 문자와 기호로도 표현 가능
- 문자
- r
- 빨간색
- b
- 파란색
- s
- 네모
- g
- 초록색
- 기호
- --
- 점선
- ^
- 삼각형
- color 옵션
- 선 색
- linestyle 옵션
- 선 모양
- marker
- 점 모양
- markerfacecolor
- 점 색
- markersize
- 점 크기
plt.scatter(x데이터, y데이터)
- 점을 뿌리듯이 그리는 그림. 점만으로 표현
- c 옵션
- 색깔을 단계로 지정
plt.text(x좌표, y좌표, 표시글자, fontsize = 숫자)
- 글자를 찍는 함수
- 좌표값이 데이터와 동일하면 가리게 되므로 x좌표값 * 1.02
혹은 y좌표값 * 0.98
등으로 표시한다
plt.colorbar()
- 각 단계별 색 표현하는 함수
plt.xilm([시작, 끝])
- x축 범위를 시작과 끝으로 지정 가능
- x를 y로 바꾸면 y축도 동일하게 적용됨
plt.grid()
- 그래프 격자 그리는 함수
- 내부 값 디폴트: True
plt.legend()
- 라벨 범례 표현하는 함수
- labels 옵션
- 범례 종류를 나타내는 옵션
- plot 내부에 범례를 표시한 경우 생략가능
- 리스트 값으로 표현 가능
- loc 옵션
- 범례 위치
- best가 디폴트로 총 11가지 존재하며 string 혹은 integer로 표시 가능
plt.xlabel("x축이름")
- x축 이름 달아줘
- x를 y로 바꾸면 y축도 동일하게 적용됨
plt.title("그래프 이름")
- 그래프 이름 달아줘
plt.show()
- 그래프 보여줘
numpy 기능
numpy.arange(a, b, s)
- a부터 b가지의 s의 간격
numpy.sin(value)
- value에 대응하는 sin값을 출력
- sin자리에 cos를 넣으면 cos값 출력
- numpy를 이용하여 1차 직선 만들기
- np.polyfit(x데이터, y데이터, 차수)
- 직선을 구성하기 위한 계수 계산
- 차수 옵션은 숫자로 바로 사용 가능
- np.poly1d(계수)
- polyfit으로 찾은 계수로 python에서 사용할 함수로 만들어 줌
- 직선을 구성하는 두 개의 계수를 넣음
- 이 결과값에 (x값)을 넣으면 예측 y값을 출력
- np.linsplace(a, b, n)
- a부터 b까지 n개의 등간격 데이터 생성
- 경향선을 위한 x데이터 생성
- 이 값을 np.npoly1d의 결과 1차 함수에 활용
pandas에서 matplotlib 기능 가져와 사용하기
df.plot(kind = '모양', figsize = (n, m), grid = True);
- kind 옵션
- 'bar'
- 'barh'
- 'line'
- figsize 옵션
- (n, m)
- grid 옵션
- True / False
- 마지막 ;
표시하면 메모리 번지가 보이지 않음
- 주피터 노트북은 셀 내부 마지막에 변수가 존재하면, 변수값을 보여줌. plot의 변수값은 메모리 번지인듯. 그것을 보여주지 않으려면 ;을 붙이면 됨 왤까???
인구현황 데이터 훑어보기
- 전체 숫자 오름차순, 내림차순 정렬
- 최근 증가율 확인 위해 최근 3년간 그 전 보유한 갯수 대비 많이 설치한 것으로 정리
- 2016 + 2015 + 2014 / 2013 이전 *100
- unique() 함수 이용하여 데이터 초반 검증 필요
- 각 요소의 합계도 보아야 하지만, 비율도 보아야 한다
- 특정 컬럼을 골라 sort_values()를 한 결과를 보면 정렬이 되어 데이터를 되어 보기 좋다
- 주피터 노트북 내에 망치 모양 뭐지???
CCTV 데이터 경향
- 데이터 경향 그려보기
- 단순한 소계
- 중요 지수 대비 비율
- 선형회귀 활용 -> 간단히 numpy 활용
- 비율과 데이터, 전체 경향 함께 보기
- 경향에서 벗어난 데이터 강조하기
- 실제값과 경향과의 차이를 오차 컬럼을 만들어 표현하기
- 오름차순, 내림차순 둘 다 보여주기
- 오차 컬럼 내 상위, 하위 5개만 표시하는 등 선택적으로 글씨와 함께 특별한 색을 사용하면 EDA용 시각화자료로 괜찮음
서울시 범죄 현황 데이터 분석
강남3구 범죄 현황 데이터 특징 정리하기
- 데이터 과학의 목적
- 가정(인식)을 검증하고 표현하는 것
데이터 개요
- 서울시 관서별 5대 범죄 현황 > 데이터 수집
thousands = ","
- pd.read_csv로 부를 때, 숫자에 콤마가 있는 경우 활용할 수 있는 옵션
- 문자 인식될 수 있지만, 콤마 제거 후 숫자로 읽는 것이 가능해짐
df.info()
로 확인한 후 실제 데이터 갯수와 RangeIndex 범위를 비교해 보면 정리해야 하는 데이터가 얼마나 있는지 확인할 수 있다
df[df['특정컬럼'].isnull()]
- 특정 컬럼에 NaN이 있는 데이터만 따로 확인해보기
df = df[df['특정컬럼'].notnull()]
- NaN 컬럼을 제거하지 말고, NaN이 아닌 데이터만 불러오기
pandas의 pivot_table
pd.pivot_table(df, index = ["컬럼명", ...], values = ["컬럼명", ...], columns = ["컬럼명", ...], aggfunc = [함수, ...], margins = True)
- 컬럼명을 인덱스로 재정렬해줌
- df.pivot_table()
로 사용해도 동일한 결과가 나옴
- 옵션의 값들이 한 개일 경우 일반적인 표현, 여러 개일 경우 리스트 형태로 표현
- 인덱스를 여러 개 지정한 경우, 제일 첫 번째 요소에 맞추고 뒤로 갈 수록 중복될 수 있다
- values 옵션으로 보고 싶은 컬럼을 지정할 수 있음
- columns 옵션
- 분류를 지정
- 없는 데이터는 NaN으로 표시
- fill_value = 값
- NaN에 대한 표시를 지정해주는 옵션
- aggfunc 옵션
- 중복 데이터를 정리하는 방식
- 디폴트: 평균
- 함수를 값으로 받음
- 함수를 리스트 형태로 여러 개 받을 수 있음. 하나의 컬럼에서 평균, 총합 등으로 계산한 값이 따로 가능
- margins 옵션
- False 값이 디폴트
- True이면 총계값 나옴
데이터 정리
- index를 경찰서 이름, columns를 죄종, 발생검거로, aggfunc을 덧셈으로 활용하여 pivot_table을 만들어본다
- 컬럼이 multi로 잡혀 보기 불편함
- df["함수명", "계산된 컬럼명", "죄종값", "발생검거값"]
등으로 접근해야 함
- level 0~n까지 순서대로 나옴
- df.columns.droplevel([0, 1, ...])
- 다중 컬럼에서 특정 컬럼을 제거
- 위 값을 df.columns로 다시 재배정함
- inplace 옵션이 있는지 확인
- df.columns의 결과가 MultiIndex일 경우, 마지막에 names 값을 확인해보기
- None이라고 되어있을 경우 종류가 여러 개라는 것이 아니므로 삭제해도 괜찮을지도...? 다만 pivot한 과정을 어딘가에 메모해두어 컬럼의 속성을 기억해둘 필요 있음
- 경찰서 이름 > 구 이름 변환 등이 필요함
- 커뮤니케이션 능력
- 보고서 능력
- 목적을 상기하여 지역별 분석이었으므로 이름을 지역으로 치환하는 것이 필요
pip 명령과 conda 명령
- anaconda가 많은 python 모듈을 포함한 배포판이라 따로 설치할 일이 없음
- pip 명령
- python의 공식 모듈 관리자
- pip list
- 현재 설치된 모듈 리스트 반환
- pip install module_name
- 모듈 설치
- pip uninstall module_name
- 설치된 모듈 제거
- 주피터 노트북에서는 !를 앞에 붙이면 os레벨 명령 사용 가능
- !pip list
- 주피터 노트북 안쓰고 바로 코드를 export 하여 사용하면 !명령어는 에러 발생
- get_ipython().system("pip list")
- conda 명령
- anaconda에서 배포한 모듈 관리자
- pip 명령은 conda환경에서 dependency 관리가 정확하지 않을 수 있으므로 가급적 conda를 사용하는 것이 좋음
- 모든 모듈이 conda로 설치되지 X
- codna list
- 설치된 모듈 list
- conda install module_name
- 모듈 설치
- conda uninstall module_name
- 모듈 제거
- conda install -c channel_name module_name
- 지정된 배포 채널에서 모듈 설치
google maps api 사용
- conda install googlemaps를 검색
- conda-forge 채널에서 설치하기
- python 세계 모듈간 dependency문제와 개인 PC 환경의 indivisual diffence로 인한 문제가 있음
conda install -c conda-forge googlemaps
- Google Map API key가 필요
- 구글 클라우드 결제 계정 링크에 접속
- 계정만들기
- ds_study로 이름 만들기
- 개인정보 입력하기
- 탐색메뉴> API 및 서비스 > 사용자 인증 정보 선택
- 사용자 인증 정보 만들기 > API 키 선택
- 발급된 키 복사 후 저장 > 키 제한 선택
- API 및 서비스 > 사용자 인증 정보 > 키 제한 선택 > Geocoding API 선택 > 저장
import googlemaps
gmaps_key = "복사한 키값"
gmaps = googlemaps.Client(key = gmaps_key)
gmaps.geocode("서울영등포경찰서", language = "ko")
python for 문
for n in [1, 2, 3, 4]:
print(n)
# list comprehension
[n for n in range(1, 5)]
- pandas의 iterrows()
- pandas DF는 대부분 2차원인데, for문을 이용하면 가독성이 떨어짐
- itterows() 옵션을 사용하면 편함
- 인덱스와 내용으로 나누어 받는 것을 주의
google maps에서 구별 정보 얻어 데이터 정리
import googlemaps
gmaps_key = "복사한 키값"
gmaps = googlemaps.Client(key = gmaps_key)
gmaps.geocode("서울영등포경찰서", language = "ko")
- api를 불러온 결과는 리스트 형태이고 각 값이 딕셔너리 형태이다.
- 딕셔너리에서 데이터 얻는 get 명령어를 활용
- 전체 주소에서 필요한 구 이름만 가져온다
- 경찰서 이름에서 소속된 구이름, 위도, 경도 정보 저장하기 위한 컬럼을 np.nan으로 채워 생성
- iterrows()를 이용해 인덱스와 그에 해당하는 행을 받아 반복문을 수행
- 구글 검색을 용이하게 하기 위해 검색어를 가급적 상세하게 잡아준다
- 범죄의 발생과 검거를 합쳐 표현하고 싶다
- get_level_values(0)[0] + get_level_values(1)[0]
를 반복적으로 활용
구별 데이터로 변경
pd.read_csv(index_col = 0)
index_col 옵션을 통해 인덱스를 지정할 수 있음
- 구별로 pivot하기, 이때 활용 함수는 sum
- 활용 함수에 맞지 않는 위도와 경도는 삭제
- 검거율 컬럼 만들기
- 다수의 컬럼을 다수의 컬럼으로 나누기
- df[컬럼명리스트] = df[분자리스트].div(df[분모리스트].values) ** 100
- 검거 컬럼 삭제
- 실제로는 발생 연도, 검거 연도를 구분 분석해야 하지만, 일단은 디테일하게 하지 않는다고 가정하고 heatmap 그래프에서 문제될 가능성이 있어 100이상 수치는 100으로 바꾼다
- df[df[컬럼명리스트] > 100] = 100
- 만약 모듈 버전과 의존성 문제로 작동하지 않는 경우 for문을 활용
- 컬럼 이름 변경
- df.rename(columns = {"원래이름": "나중이름", ...}, inplace = True)
범죄현황 데이터 최종 정리
- 범죄 특성 상 경중에 따라 발생 건수의 차이가 크다. 예로 살인은 한 자리수, 절도는 네 자리수 발생임
- 시각화 후 비교가 어려워진다
- 본래 DF는 두고, 정규화한 데이터를 만든다.
- min-max scailing
- 최고값:1, 최솟값: 0
- df = df[리스트변수]/df[리스트변수].max()
- 스케일링한 자료에 검거율 자료를 이어 붙인다
- df1[리스트변수] = df2[리스트변수]
를 활용하면 df1에 df2값을 가로로 이어붙일 수 있다. 이때 리스트 변수는 이어붙이기 원하는 컬럼명들의 나열
- 범죄 스케일링 데이터 + 범죄 검거율 데이터 + 인구 데이터 + CCTV 데이터 + 정규화된 범죄 데이터의 평균 데이터
- 이후에 범죄별로 가중치를 더해서 평균을 내는 방법도 존재함
- np.mean(np.array([여러 데이터 나열1], [여러 데이터 나열2], ...), axis = 1)
- 결과값: 여러 데이터 나열1의 평균, 여러 데이터 나열2의 평균, ...
- axis = 1이면 행을 기준, 디폴트값
seaborn 사용
!conda install -y seaborn
- seabon 깔기
import seaborn as sns
- matplotlib과 함께 실행된다
- 임포트만 시켜도 matplotlib 결과가 seaborn 스타일로 바뀐다
sns.load_dataset("")
- 연습용 데이터 제공해줌
plt.plot(x데이터1, y데이터1, x데이터2, y데이터2, x데이터3, y데이터3, ...)
등으로 여러 그래프 그릴 수 있음
- 개별 설정은 불가능
sns.set_style("문자")
- white, whitegrid, dark, darkgrid, stick 등 이 존재함
sns.despine(offset = 10)
- 그래프 중심점이 10만큼 떨어짐
sns.boxplot(x = x데이터, y = y데이터, data = 원천 데이터, hue = "", palette = "")
- 원천 데이터를 먼저 고르고 x데이터와 y데이터는 컬럼명으로 선택 가능
- hue 옵션
- 종류따라 구분 하고 싶은 컬럼
- palett 옵션
- 색상표 선택
sns.swarmplot(x = "", y = "", data = 원천 데이터, color = "")
- 데이터 분포를 볼 수 있음
- 박스플랏과 함게 콜라보하면 좋음
- color 옵션
- 낮아질수록 검은색, 높아질수록 흰색이 됨
sns.lmplot(x = "", y = "", data = 원천 데이터, hue = "", ci = None, order = 1, size = 숫자), roubust = False
- 회귀선 + 산점도 동시에 그려주는 그래프
- size 옵션
- 그래프의 크기
- 정수 한 개 입력
- height로 이름 바뀜
- hue 옵션
- 종류따라 구분 하고 싶은 컬럼
- 컬럼의 종류별 산점도 + 회귀선을 동시에 볼 수 있다
- ci 옵션
- 회귀선 근처 흐릿한 부분
- None으로 두면 회귀선 근처 흐릿한 부분이 사라짐
- 디폴트: None 아님
- scatter_kws 옵션
- 산점도 크기와 값을 표현
- {"문자" = 값} 속성의 이름을 문자에, 해당되는 값을 할당
- order 옵션
- 회귀선의 차수
- 디폴트: 1
- robust 옵션
- 이상값을 포함할지 여부
- 디폴트: False, 이상값 모두 포함함
sns.heatmap(데이터, annot = True, fmt = "", cmap = "")
- annot 옵션
- 네모 상자마다 값 표시
- True / False
- fmt 옵션
- 소수점 표시 여부
- d: 정수형
- f: 실수형
- cmap 옵션
- 색상표
- linewidths 옵션
- 표 칸 간격 표시
- 숫자 표시
sns.pairplot(데이터, hue = "")
- 다수의 컬럼을 비교할 때 사용
- 특성별 상관관계를 표시
- hue 옵션
- 종류따라 구분 하고 싶은 컬럼
- 기준 컬럼별로 특성별 상관관계를 겹치게 그려줌
- 이때, 원하는 컬럼만 선택하려면 x_vars = [], y_vars = []
옵션을 사용하여 리스트 내부에 원하는 컬럼명을 순서대로 넣어준다
- kind 옵션
- reg: 회귀
- scatter: 산점도
- kde: 지형도
- hist: 히스토그램
- height 옵션
- 산점도 크기
- 이전에는 size
df.query("컬럼명 == '문자'")
- 해당 컬럼이 문자와 동일한 데이터만 가져와라
범죄현황데이터 시각화
- 각 범죄간의 상관관계 확인
- 강도가 살인으로 연결되는 것 보다 폭력이 살인으로 연결될 가능성이 높지 않을까 가설 후보로 둘 수 있음
- 자료의 갯수가 많지 않아 확실히 알 수는 없음
- 인구수, CCTV와 범죄들의 상관관계를 확인
- 소수의 이상점을 포함한 회귀선은 오류가 있을 수 있으므로 그것을 제외한 관계를 보는 것이 좋다
- 인과관계가 아니라 상관관계이므로 가설을 세울 때 유의해야함
- 인구수, CCTV와 범죄 검거율의 상관관계를 확인
- 검거율을 맨 처음 100이상을 100으로 제한하여 대부분이 100에 몰려있음
- 검거율로 heatmap, 정규화된 검거율의 대표값인 검거의 합을 기준으로 정렬
- 범죄발생 건수로 heatmap, 대표값으로 정규화된 발생 건수로 정렬
- 강남 3구 범죄 발생 건수가 낮지 않고, 범죄 검거율이 높지 않다. 인구대비 현황을 고려해야 할 것이다.
Folium 지도 시각화
- 크롬에서 동작이 가장 좋은 지도 시각화 도구
conda install -c conda -forge folium
- 설치에 문제가 있어
- !pip install folium
으로 설치
- !pip install charset
, !pip install charset-normalizer
설치하면 오류가 적어짐(windows한정)
- 위도와 경도 좌표만 입력해도 지도가 표시됨
- folium.Map(location = [위도, 경도])
- 지도를 html로 저장 가능
- 지도.save('파일경로/파일명.html')
- 주피터 노트북 환경이 아닐 때, 결과보기위함
folium.Map(location = [위도, 경도], tiles = '스타일', zoom_start = 크기)
- zoom_start 옵션
- 확대 크기를 지정
- 허용 범위: 0~18
- 디폴트: 10
- tiles 옵션
- 지도 스타일 바꿔줌
- 디폴트: OpenStreetMap
- 여러 종류 있음
- 마커를 추가
- folium.Marker(location = [위도, 경도]).add_to(지도이름)
folium.Marker(location = [위도, 경도], popup = '나올 멘트와 형식', tooltip = '나올 멘트와 형식', icon = folium.Icon(icon = 모양, color = 색깔)).add_to(지도이름)
- popup 옵션
- 문자타입으로 입력
- 클릭하면 입력한 글씨가 출력됨
- html 문법 적용 가능
- <a href = "연결주소" target = _'blink'>표시글자</a>
- 표시 글자가 작성되어있고, 클릭하면 연결주소로 새창이 열림
- tooltip 옵션
- 문자타입으로 입력
- 갖다대기만 하면 글씨가 출력됨
- html 문법 적용 가능
- icon 옵션
- folium.Icon()
를 불러옴
- color 옵션
- 문자로 입력가능
- 아이콘 둘러싼 것의 색깔
- 디폴트: 파랑
- icon_color 옵션
- 아이콘 자체의 색깔
- 디폴트: 하양
- icon 옵션
- 표현되는 아이콘 모양
- 디폴트: info-sign
- angle 옵션
- 가운데 아이콘의 기울어짐 정도
- 시계방향
- 디폴트: 0
- prefix 옵션
- fa 값일 경우
- font-awsome 참조
- 디폴트: glyphicon
- getbootsrap 참조
지도이름.add_child(folium.ClickForMarker(popup = '표시 문구'))
- 지도를 클릭한 곳에 마커가 생성됨
- popup 옵션
- 문자 입력으로 표시문구가 반환
- 디폴트: 위도, 경도
지도이름.add_child(folium.LatLngPopup())
- 지도 클릭한 곳에 위도 경도를 반환해줌
- 옵션 X
folium.Circle(location = [위도, 경도], radius = 반지름 크기, popup = '나올 멘트와 형식', tooltip = '나올 멘트와 형식', color = "색깔", fill = False, fill_color = 색깔)
- radius 옵션
- 반지름 크기
- 디폴트: 10
- color 옵션
- 선 색깔
- fill 옵션
- True 일 경우, 내부 색상 채워짐
- 디폴트: False
- fill_color 옵션
- fill이 True일 경우 채워질 색상
folium.CircleMarker(location = [위도, 경도], radius = 반지름 크기, popup = '나올 멘트와 형식', tooltip = '나올 멘트와 형식', color = "색깔", fill = False, fill_color = 색깔)
- Circle보다 원형 크기가 훨씬 큼
- 공식문서에서도 정확한 차이 기술 X
- 클릭으로 위도 경도 정보 반환
- folium.Map(~~).add_child(folium.LatLngPopup())
- 지도에 colormap 표현
- us_states.json 파일 이용해 경계선과 id를 각 지역에 구현
- json 라이브러리 임포트 필요
- us_unemployment csv파일에 위의 json 파일과 매칭되는 id와 값을 갖게 함
- 지도.Choropleth(geo_data = '활용 json 데이터', data = 활용 데이터, columns = [활용 컬럼들 나열], key_on = '공유 기준 컬럼', fill_color = '색', fill_opacity = 색 진하기 수치, line_opacity = 색 진하기 수치, legend_name = '표시 이름'
- 경계선을 하나의 덩어리로 잡고 색을 입힐 수 있음
- geo_data 옵션
- 경계선 좌표값이 담긴 데이터
- data 옵션
- 활용 데이터
- Pandas의 DataFrame, Series 로 이루어져야 함
- columns 옵션
- 활용 데이터에서 사용할 컬럼
- key_on 옵션
- 문자값
- 활용 지도 데이터와 활용 데이터 사이 공통된 key 컬럼 이름
- feature.id 혹은 feature.properties.statename
- fill_color 옵션
- 채우는 색
- fill_opacity 옵션
- 채우는 색 흐린 정도
- 0~1 사이
- line_opacity 옵션
- 선 흐린 정도
- 0~1 사이
- legend_name 옵션
- 범례 이름
아파트 유형 지도 시각화
- 공공데이터 포털 참조
- pandas의 DataFrame으로 부름
- DataFrame.info()로 데이터 상태 확인
- NaN 데이터 제거
- df.dropna()
- 인덱스 리셋
- df.reset_index(drop = True)
- for 문과 iterrows() 함수 활용하여 각 행별로 세대 수에 따라 색을 다르게 표현
for idx, rows in df.iterrows():
lat, lng = row.위도, row.경도
# marker
folium.Markar(
location = [lat, lng],
popup = rows.주소,
tooltip = rows.분류,
icon = folium.Icon(
icon = 'home',
colors = "lightred" if rows.세대수 >= 199 else "lightblue"
icon_color = 'darkred' if rows.세대수 >= 199 else "darkblue"
)
).add_to(지도이미지)
# CircleMarker
folium.CircleMarkar(
location = [lat, lng],
radius = rows.세대수 * 0.2,
fill = True,
color = "pink" if rows.세대수 >= 518 else "green",
fill_color = "pink" if rows.세대수 >= 518 else "green"
)
).add_to(지도이미지)
서울시 범죄현황 지도 시각화 및 장소별 분석
지도시각화
- 지도시각화에 필요한 json 파일 > 현재 무료는 Lucy Park 자료가 유일
- 각 범죄별, 범죄 전체, 인구대비 범죄 데이터를 지도에 시각화하기
- 각 범죄별 검거의 평균값을 검거 컬럼으로 넣고 경찰서별 정보를 이용해 범죄발생과 함께 정리
- 각 범죄 검거 컬럼을 컬럼 내 최댓값으로 나누어 정규화한 값의 평균을 구하여 검거 라는 컬럼을 만듬
- 이때, np.mean() 옵션의 axis = 1이 행으로 다른 것과 다름에 주의
- 실습 중 crime_in_Seoul_row 파일로 실습이 잘 안 될 경우, crime_in_Seoul_1st 파일을 활용하면 잘 될 것
장소별 분석
- 강남 3구 > 유흥업소가 몰려있어서 그럴 수 있다는 가설을 확인하기 위함
- 최초 받았던 발생 장소별 데이터를 읽어보기
- 장소 컬럼을 unique() 함수로 무엇이 있는지 확인해보기
- pd.DataFrame.pivot_table() 함수를 활용하여 index = 장소,. columns = 범죄명, aggfunc = np.sum 으로 장소별 범죄의 합을 보기
- 각 범죄를 각 범죄별 최댓값으로 나누어 정규화하기
- 정규화된 각 범죄의 평균을 구함
- droplevel로 멀티컬럼 지울 것 지우기, 맨 위가 0번
- heatmap으로 확인하기
- 노상에서 많이 일어남
- 범죄가 시작되기 전 상태가 아니라, 발생한 순간의 장소임을 확인
느낀점
단순히 프로그래밍을 할 줄 아는 것이 아니라, 어떤 데이터를 특정한 모양으로 보고 싶다 혹은 어떠한 이유로 이런 데이터들을 정리하고 싶다와 같이 데이터를 파고드는 힘이 있어야한다는 것을 알았다.
이 글은 제로베이스 데이터 취업 스쿨의 강의 자료 일부를 발췌하여 작성되었습니다.