python, pandas
1. 서울시 구별 CCTV 현황 데이터 확보
2. 인구 현황 데이터 확보
3. CCTV 데이터와 인구 현황 데이터 합치기
4. 데이터를 정리하고 정렬
Matplotlib
5. 그래프 그리기
Regression using Numpy
6. 전체적인 경향 파악
Insight and Visualization
7. 경향에서 벗어난 데이터 강조
import pandas as pd
CCTV_Seoul.rename(columns={CCTV_Seoul.columns[0]: "구별"}, inplace = True)
CCTV_Seoul.head()
inplace=True를 해줘야지 다음번에 조회를 했을때에도 변경된 column이름으로 확인할 수 있다.
상단 두개의 데이터가 필요없어 보인다.
-> 일단 원본 excel 파일부터 확인
-> 원래 그렇게 만들어진 엑셀 파일이였다.
pop_Seoul = pd.read_excel(
"../data/01. Seoul_Population.xls", header=2, usecols="B,D,G,J,N"
)
pop_Seoul.rename(
columns={
pop_Seoul.columns[0]: "구별",
pop_Seoul.columns[1]: "인구수",
pop_Seoul.columns[2]: "한국인",
pop_Seoul.columns[3]: "외국인",
pop_Seoul.columns[4]: "고령자"
},
inplace=True
)
pop_Seoul.head()
DataFrame의 index 확인 - df.index
DataFrame의 columns 확인 - df.columns
DataFrame의 value 확인 - df.values
DataFrame의 기본 정보 확인 - df.info : 여기서는 각 column의 크기와 데이터형태를 확인하는 경우가 많다.
DataFrame의 통계적 기본 정보를 확인 - df.describe()
데이터 정렬
df.sort_values(by="B", ascending=False)
특정 컬럼만 읽기 :
df["A"]
df[0:3]
df[n:m] : n부터 m-1까지 (그러나 인덱스나 컬럼의 이름으로 slice하는 경우는 끝을 포함함)
loc
loc : location
index의 이름으로 특정 행이나 열을 선택
A 컬럼의 양수만 보고 싶을 때 :
df[df["A"] > 0]
컬럼 추가
기존 컬럼이 없으면 추가
기존 컬럼이 있으면 수정
isin() : 특정 요소가 있는지 확인
df["E"].isin(["two","four"])
특정 요소가 있는 행만 선택
df[df["E"].isin(["two","four"])]
특정 컬럼 제거
del df["E"]
: numpy함수도 사용가능하다
: 함수를 적용해서도 사용가능 하다.
CCTV_Seoul.sort_values(by="소계", ascending=True).head(5)
(소계를 기준으로 오름차순 다섯개. ascending=True는 디폴트값이라 안써도 된다)
CCTV_Seoul.sort_values(by="소계", ascending=False).head(5)
CCTV_Seoul["최근증가율"] = (
(CCTV_Seoul["2016년"]+ CCTV_Seoul["2015년"] + CCTV_Seoul["2014년"]) /CCTV_Seoul["2013년도 이전"] * 100
)
CCTV_Seoul.sort_values(by="최근증가율", ascending=False).head(5)
pop_Seoul["구별"].unique()
len(pop_Seoul["구별"].unique()) : 데이터가 많아지면 unique조사를 통해 데이터를 초반 검증한다.
pop_Seoul["외국인 비율"] = pop_Seoul["외국인"] / pop_Seoul["인구수"] 100
pop_Seoul["고령자 비율"] = pop_Seoul["고령자"] / pop_Seoul["인구수"] 100
pop_Seoul.head()
(컬럼 연산이 편하다는 것이 python의 장점)
pop_Seoul.sort_values(["인구수"],ascending=False).head(5)
pop_Seoul.sort_values(["외국인"],ascending=False).head(5)
pop_Seoul.sort_values(["외국인 비율"],ascending=False).head(5)
pd.merge(left,right, on="key")
key 컬럼을 기준으로 병합
how="inner"값이 디폴트값이다. 교집합이라는 뜻
pd.merge(left,right, how="left", on="key")
left에 key를 기준으로 right병합
pd.merge(left,right, how="outer", on="key")
합집합으로 결합하겠다는 뜻
data_result.set_index("구별", inplace=True)
data_result.head()
두 변량 사이에 한쪽이 증가하면 다른 쪽도 증가(또는 감소)하는 경향이 있을 때,
이 두 변량 사이에는 상관관계가 있다고 함
단, 상관관계가 있다하여 두 변량이 인과관계인 것은 아님
0.2이하 : 상관관계가 없거나 무시해도 좋은 수준
0.4이하 : 약한 상관관계
0.6이상 : 강한 상관관계
corr() : 상관계수가 0.2이상인 데이터를 비교
(데이터의 관계를 찾을 때, 최소한의 근거가 있어야 해당 데이터를 비교하는 의미가 존재
상관계수를 조사해서 0.2 이상의 데이터를 비교하는 것은 의미가 있다.)
import matplotlib.pyplot as plt
from matplotlib import rc
rc("font", family="Arial Unicode MS")
# %matplotlib inline
get_ipython().run_line_magic("matplotlib","inline")
import numpy as np
t = np.arange(0,12,0.01)
y = np.sin(t)
plt.figure(figsize=(10,6))
plt.plot(t,np.sin(t))
plt.plot(t,np.cos(t))
plt.show()
그래프를 예쁘게 그리려면
def drawGraph():
plt.figure(figsize=(10,6))
plt.plot(t,np.sin(t))
# plt.plot(t,np.sin(t), label="sin")
plt.plot(t,np.cos(t))
# plt.plot(t,np.sin(t), label="cos")
plt.grid(True)
plt.legend(labels=["sin","cos"]) # 범례
# plt.legend()
plt.title("Example of sinwave")
plt.xlabel("time")
plt.ylabel("Amplitude") # 진폭
plt.show()
t = np.arange(0, 5, 0.5)
t
plt.figure(figsize=(10,6))
plt.plot(t, t, "r--") # red ---
plt.plot(t, t ** 2, "bs") # blue square
plt.plot(t, t ** 3, "g^") # green triangle
plt.show()
# t = [0, 1, 2, 3, 4, 5, 6]
t = list(range(0,7))
y = [1, 4, 5, 8 ,9, 5, 3]
def drawGraph():
plt.figure(figsize=(10,6))
plt.plot(
t,
y,
color = "green",
linestyle = "dashed", # 점선
marker="o", # 포인트마다 동그라미
markerfacecolor="blue",
markersize=15,
)
plt.xlim([-0.5,6.5])
plt.ylim([0.5,9.5])
plt.show()
drawGraph()
t = np.array(range(0,10))
y = np.array([9,8,7,9,8,3,2,4,3,4])
def drawGraph():
plt.figure(figsize=(10,6))
plt.scatter(t,y)
plt.show()
drawGraph()
colormap = t
def drawGraph():
plt.figure(figsize=(20,6))
# s : 포인터 사이즈
plt.scatter(t,y, s=100, c=colormap, marker=">")
plt.colorbar()
plt.show()
drawGraph()
def drawGraph():
data_result["소계"].sort_values().plot(
kind="barh", grid=True, title="가장 CCTV가 많은 구",figsize=(10,10));
drawGraph()
경향을 파악할 필요
def drawGraph():
plt.figure(figsize=(14,10))
plt.scatter(data_result["인구수"],data_result["소계"],s=50)
plt.xlabel("인구수")
plt.ylabel("CCTV")
plt.grid(True)
plt.show()
drawGraph()
numpy를 이용한 1차 직선 만들기
def drawGraph():
plt.figure(figsize=(14,10))
plt.scatter(data_result["인구수"],data_result["소계"],s=50)
plt.plot(fx,f1(fx), ls="dashed",lw=3, color="green")
plt.xlabel("인구수")
plt.ylabel("CCTV")
plt.grid(True)
plt.show()
drawGraph()
fp1 = np.polyfit(data_result["인구수"], data_result["소계"],1)
f1 = np.poly1d(fp1)
fx = np.linspace(100000, 700000, 100)
data_result["오차"] = data_result["소계"] - f1(data_result["인구수"])
# 경향과 비교해서 데이터의 오차가 너무 나는 데이터를 계산
df_sort_f = data_result.sort_values(by="오차",ascending=False) # 내림차순
df_sort_t = data_result.sort_values(by="오차",ascending=True) # 오름차순
# 경향 대비 CCTV를 많이 가진 구
df_sort_f.head()
# 경향 대비 CCTV를 적게 가진 구
df_sort_t.head()
from matplotlib.colors import ListedColormap
# colormap 을 사용자 정의(user define)로 세팅
color_step = ["#e74c3c","#2ecc71","#95a9a6","#2ecc71","#3498db","#3498db"]
my_cmap = ListedColormap(color_step)
def drawGraph():
plt.figure(figsize=(14,10))
plt.scatter(data_result["인구수"],data_result["소계"],s=50,c=data_result["오차"],cmap=my_cmap)
plt.plot(fx,f1(fx), ls="dashed",lw=3, color="g")
for n in range(5):
# 상위 5개
plt.text(
df_sort_f["인구수"][n] * 1.02, # x 좌표
df_sort_f["소계"][n] * 0.98, # y 좌표
df_sort_f.index[n], # title
fontsize=15,
)
# 하위 5개
plt.text(
df_sort_t["인구수"][n] * 1.02, # x 좌표
df_sort_t["소계"][n] * 0.98, # y 좌표
df_sort_t.index[n], # title
fontsize=15,
)
plt.text(df_sort_f["인구수"][0] * 1.02, df_sort_f["소계"][0]*0.98,df_sort_f.index[0], fontsize=15)
plt.xlabel("인구수")
plt.ylabel("CCTV")
plt.colorbar()
plt.grid(True)
plt.show()
drawGraph()
data_result.to_csv("../data/01. CCTV_result.csv", sep=",", encoding="utf-8")