import pandas as pd
import numpy as np
# 데이터 읽기, 숫자값 천단위 ',' 처리
crime_raw_data = pd.read_csv("02. crime_in_Seoul.csv", thousands=",", encoding="euc-kr")
crime_raw_data.head()
crime_raw_data.info()
info()로 데이터 개요를 확인해 보니, rangeindex가 65534개인데 310개로 나와있다.
crime_raw_data["죄종"].unique()
#출력 : array(['살인', '강도', '강간', '절도', '폭력', nan], dtype=object)
#Nan이 존재
# null 찾기
crime_raw_data[crime_raw_data["죄종"].isnull()].head()
# null 제거
crime_raw_data = crime_raw_data[crime_raw_data["죄종"].notnull()]
다시 info()로 확인해보니 null값이 제거된 것을 확인할 수 있다.
#예시로 사용할 데이터 불러오기
df = pd.read_excel("02. sales-funnel.xlsx")
df.head()
# Name 컬럼을 인덱스로 설정
pd.pivot_table(df, index="Name")
#멀티 인덱스 설정
df.pivot_table(index=["Name", "Rep", "Manager"])
#values 설정
df.pivot_table(index=["Manager", "Rep"], values = "Price")
#Price컬럼 sum 연산 적용
df.pivot_table(index=["Manager", "Rep"], values="Price", aggfunc=[np.sum, len])
# Product를 컬럼으로 설정
df.pivot_table(index=["Manager", "Rep"], values="Price", columns="Product", aggfunc=np.sum)
# Nan 값 설정 : fill_value
df.pivot_table(index=["Manager", "Rep"], values="Price", columns="Product", aggfunc=np.sum, fill_value=0)
#aggfunc 2개 이상 설정
df.pivot_table(
index=["Manager", "Rep", "Product"],
values=["Price", "Quantity"],
aggfunc=[np.sum, np.mean],
fill_value=0,
margins=True #총계(All) 추가
)
crime_station = crime_raw_data.pivot_table(index="구분", columns=["죄종", "발생검거"], aggfunc=[np.sum])
crime_station.head()
crime_station.columns
#다중 컬럼에서 특정 컬럼 제거
crime_station.columns = crime_station.columns.droplevel([0,1])
crime_station.columns
#정리된 데이터 확인
crime_station.head()
crime_station.index
Pandas에 잘 맞춰진 반복문용 명령 iterrows()
- Pandas 데이터 프레임은 대부분 2차원
- 이럴 때 for문을 이용하면, n번째라는 지정을 반복해서 가독률이 떨어짐
- Pandas 데이터 프레임으로 반복문을 만들 때 iterrows()옵션을 사용하면 편함
- 받을 때, 인덱스와 내용으로 나누어 받는 것만 주의
# 구글에서 내키 받기
import googlemaps
gmaps_key = "내키"
gmaps = googlemaps.Client(key=gmaps_key)
#단순 테스트 코드
tmp = gmaps.geocode("서울영등포경찰서", language="ko")
tmp
# 구별 , lat, lng 컬럼생성
crime_station["구별"] = np.nan
crime_station["lat"] = np.nan
crime_station["lng"] = np.nan
crime_station.head()
이제부터....
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"]
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.columns = tmp
crime_station.head()
# index_col "구분"을 인덱스 컬럼으로 설정
crime_anal_station = pd.read_csv("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()
# 검거율 생성
# 하나의 컬럼을 다른 컬럼으로 나누기
crime_anal_gu["강도검거"] / crime_anal_gu["강도발생"]
# 다수의 컬럼을 다른 컬럼으로 나누기
crime_anal_gu[["강도검거", "살인검거"]].div(crime_anal_gu["강도발생"], axis=0).head()
target = ["강간검거율", "강도검거율", "살인검거율", "절도검거율", "폭력검거율"]
num = ["강간검거", "강도검거", "살인검거", "절도검거", "폭력검거"]
den = ["강간발생", "강도발생", "살인발생", "절도발생", "폭력발생"]
crime_anal_gu[target] = crime_anal_gu[num].div(crime_anal_gu[den].values)*100
crime_anal_gu.head()
# 필요없는 컬럼 제거
crime_anal_gu.drop(["강간검거", "강도검거", "살인검거", "절도검거", "폭력검거"], axis=1, inplace=True)
crime_anal_gu.head()
# 100보다 큰 숫자 찾아서 바꾸기
crime_anal_gu[crime_anal_gu[target]>100] = 100
crime_anal_gu.head()
from os import replace
# 컬럼 이름 변경
crime_anal_gu.rename(columns={"강간발생":"강간", "살인발생":"살인", "절도발생":"절도", "강도발생":"강도", "폭력발생":"폭력"}, inplace=True)
crime_anal_gu.head()
# 정규화
col = ["살인", "강도", "강간", "절도", "폭력"]
crime_anal_norm = crime_anal_gu[col] / crime_anal_gu[col].max()
crime_anal_norm.head()
# 검거율 추가
col2 = ["강간검거율", "강도검거율", "살인검거율", "절도검거율", "폭력검거율"]
crime_anal_norm[col2] =crime_anal_gu[col2]
crime_anal_norm.head()
# 구별 CCTV 자료에서 인구수와 CCTV수 추가
result_CCTV = pd.read_csv("01. CCTV_result.csv", index_col="구별", encoding="utf-8")
crime_anal_norm[["인구수", "CCTV"]] = result_CCTV[["인구수", "소계"]]
crime_anal_norm.head()
#정규화된 범죄발생 건수 전체의 평균을 구해서 범죄 컬럼 대표값으로 사용
col= ["강간", "강도", "살인", "절도", "폭력"]
crime_anal_norm["범죄"] = np.mean(crime_anal_norm[col], axis=1) #axis=1 행, axis=0 열
crime_anal_norm.head()
# 검거율의 평균을 구해서 검거 컬럼의 대표값으로 사용
col = ["강간검거율", "강도검거율", "살인검거율", "절도검거율", "폭력검거율"]
crime_anal_norm["검거"] = np.mean(crime_anal_norm[col], axis=1) #axis=1 행을 따라서 연산하는 옵션
crime_anal_norm.head()
# np.mean 개념 np.array([0.384615, 1.000000, 1.000000, 1.000000, 1.000000]) #출력 : array([0.384615, 1. , 1. , 1. , 1. ]) np.mean(np.array([0.384615, 1.000000, 1.000000, 1.000000, 1.000000])) #출력 : 0.876923
np.linspace(0, 14, 100)
#출력:
array([ 0. , 0.14141414, 0.28282828, 0.42424242, 0.56565657,
0.70707071, 0.84848485, 0.98989899, 1.13131313, 1.27272727,
1.41414141, 1.55555556, 1.6969697 , 1.83838384, 1.97979798,
2.12121212, 2.26262626, 2.4040404 , 2.54545455, 2.68686869,
2.82828283, 2.96969697, 3.11111111, 3.25252525, 3.39393939,
3.53535354, 3.67676768, 3.81818182, 3.95959596, 4.1010101 ,
4.24242424, 4.38383838, 4.52525253, 4.66666667, 4.80808081,
4.94949495, 5.09090909, 5.23232323, 5.37373737, 5.51515152,
5.65656566, 5.7979798 , 5.93939394, 6.08080808, 6.22222222,
6.36363636, 6.50505051, 6.64646465, 6.78787879, 6.92929293,
7.07070707, 7.21212121, 7.35353535, 7.49494949, 7.63636364,
7.77777778, 7.91919192, 8.06060606, 8.2020202 , 8.34343434,
8.48484848, 8.62626263, 8.76767677, 8.90909091, 9.05050505,
9.19191919, 9.33333333, 9.47474747, 9.61616162, 9.75757576,
9.8989899 , 10.04040404, 10.18181818, 10.32323232, 10.46464646,
10.60606061, 10.74747475, 10.88888889, 11.03030303, 11.17171717,
11.31313131, 11.45454545, 11.5959596 , 11.73737374, 11.87878788,
12.02020202, 12.16161616, 12.3030303 , 12.44444444, 12.58585859,
12.72727273, 12.86868687, 13.01010101, 13.15151515, 13.29292929,
13.43434343, 13.57575758, 13.71717172, 13.85858586, 14. ])
x = np.linspace(0, 14, 100)
y1 = np.sin(x)
y2 = 2 * np.sin(x + 0.5)
y3 = 3 * np.sin(x + 1)
y4 = 4 * np.sin(x + 1.5)
plt.figure(figsize=(10,6))
plt.plot(x, y1, x, y2, x, y3, x, y4)
plt.show()
# sns.set_style()
# "white", "whitegrid", "dark", "darkgrid"
sns.set_style("darkgrid")
plt.figure(figsize=(10,6))
plt.plot(x, y1, x, y2, x, y3, x, y4)
plt.show()
tips = sns.load_dataset("tips")
tips
# boxplot
plt.figure(figsize=(8,6))
sns.boxplot(x=tips["total_bill"])
plt.show()
# boxplot
plt.figure(figsize=(8,6))
sns.boxplot(x=tips["day"], y=tips["total_bill"])
plt.show()
# boxplot hue, palette option
# hue: 카테고리 데이터를 표현하는 옵션
plt.figure(figsize=(8,6))
sns.boxplot(x="day", y="total_bill", data=tips, hue="smoker", palette="Set3")
plt.show()
#swarmplot
# color: 0-1 사이 검은색부터 흰색사이 값을 조절
plt.figure(figsize=(8, 6))
sns.swarmplot(x="day", y="total_bill", data=tips, color="0.5")
plt.show()
# boxplot with swarmplot
plt.figure(figsize=(8,6))
sns.boxplot(x="day", y="total_bill", data=tips)
sns.swarmplot(x="day", y="total_bill", data=tips, color="0.25")
plt.show()
# lmplot: total_bill 과 tip 사이 관계 파악
sns.set_style("darkgrid")
sns.lmplot(x="total_bill", y="tip", data=tips, height=7) #size => height 바뀜
plt.show()
# hue option
sns.set_style("darkgrid")
sns.lmplot(x="total_bill", y="tip", data=tips, height=7, hue="smoker")
plt.show()
flights = sns.load_dataset("flights")
flights.head()
# pivot
# index, columns, values
flights = flights.pivot_table(index="month", columns="year", values="passengers")
flights.head()
# heatmaps
plt.figure(figsize=(10, 8))
sns.heatmap(data=flights, annot=True, fmt="d") # annot=True 데이터 값 표시, fmt="d" 정수형 표현
plt.show()
# colormap
plt.figure(figsize=(10, 8))
sns.heatmap(flights, annot=True, fmt="d", cmap="YlGnBu")
plt.show()
iris = sns.load_dataset("iris")
iris.tail()
# pairplot
sns.set_style("ticks")
sns.pairplot(iris)
plt.show()
# hue option
sns.pairplot(iris, hue="species")
plt.show()
# 원하는 컬럼만 pairplot
sns.pairplot(iris,
x_vars=["sepal_width", "sepal_length"],
y_vars=["petal_width", "petal_length"]
)
plt.show()
anscombe = sns.load_dataset("anscombe")
anscombe.tail()
anscombe["dataset"]. unique()
#출력 : array(['I', 'II', 'III', 'IV'], dtype=object)
sns.set_style("darkgrid")
sns.lmplot(x="x", y="y", data=anscombe.query("dataset == 'I'"), ci = None, height=7) #ci신뢰구간 선택
plt.show()
sns.set_style("darkgrid")
sns.lmplot(x="x", y="y", data=anscombe.query("dataset == 'I'"), ci = None, height=7, scatter_kws={"s":80}) #ci신뢰구간 선택
plt.show()
# order option
sns.set_style("darkgrid")
sns.lmplot(
x="x",
y="y",
data=anscombe.query("dataset == 'II'"),
order=1,
ci = None,
height=7,
scatter_kws={'s':80}) #ci신뢰구간 선택
plt.show()
# order option
sns.set_style("darkgrid")
sns.lmplot(
x="x",
y="y",
data=anscombe.query("dataset == 'II'"),
order=2,
ci = None,
height=7,
scatter_kws={'s':80}) #ci신뢰구간 선택
plt.show()
# outlier option - 동떨어진 데이터 다루기
sns.set_style("darkgrid")
sns.lmplot(
x="x",
y="y",
data=anscombe.query("dataset == 'III'"),
ci = None,
height=7,
scatter_kws={'s':80}) #ci신뢰구간 선택
plt.show()
# outlier option - 동떨어진 데이터 다루기
sns.set_style("darkgrid")
sns.lmplot(
x="x",
y="y",
data=anscombe.query("dataset == 'III'"),
robust=True,
ci = None,
height=7,
scatter_kws={'s':80}) #ci신뢰구간 선택
plt.show()
crime_anal_norm.head()
# "인구수", "CCTV"와 "살인", "강도"의 상관관계 확인
def drawGraph():
sns.pairplot(
data = crime_anal_norm,
x_vars=["인구수", "CCTV"],
y_vars=["살인", "강도"],
kind="reg",
height=4
)
plt.show()
drawGraph()
# "인구수", "CCTV"와 "절도검거율", "강도검거율"의 상관관계 확인
def drawGraph():
sns.pairplot(
data = crime_anal_norm,
x_vars=["인구수", "CCTV"],
y_vars=["절도검거율", "강도검거율"],
kind="reg",
height=4
)
plt.show()
drawGraph()
# 검거율 heatmap
# "검거" 컬럼을 기준으로 정렬
def drawGraph():
#데이터 프레임생성
target_col = ["강간검거율","강도검거율","살인검거율","절도검거율","폭력검거율","검거"]
crime_anal_norm_sort = crime_anal_norm.sort_values(by="검거", ascending=False)
#그래프 설정
plt.figure(figsize=(10,10))
sns.heatmap(
data=crime_anal_norm_sort[target_col],
annot=True, #데이터값 표현
fmt="f", #d:정수, f:실수
linewidths=0.5, #네모칸끼리의 간격설정
cmap="RdPu"
)
plt.title("범죄 검거 비율(정규화된 검거의 합으로 정렬)")
plt.show()
drawGraph()
# 범죄발생 건수 heatmap
# "범죄" 컬럼을 기준으로 정렬
def drawGraph():
#데이터 프레임 생성
target_col=["살인", "강도", "강간", "절도", "폭력", "범죄"]
crime_anal_norm_sort = crime_anal_norm.sort_values(by="범죄", ascending=False)
#그래프 설정
plt.figure(figsize=(10,10))
sns.heatmap(
data=crime_anal_norm_sort[target_col],
annot=True,
fmt = "f",
linewidths=0.5,
cmap="RdPu"
)
plt.title("범죄 비율(정규화된 발생 건수로 정렬)")
plt.show()
drawGraph()
import folium
import pandas as pd
import json
#save()
m.save("folium.html")
!ls
#출력 :
'01. CCTV_result.csv'
'01. Seoul_CCTV.csv'
'01. Seoul_Population.xls'
'02. crime_in_Seoul_1st.csv'
'02. crime_in_Seoul.csv'
'02. crime_in_Seoul_final.csv'
'02. crime_in_Seoul_location.csv'
'02. crime_in_Seoul_raw.csv'
'02. sales-funnel.xlsx'
'02. skorea_municipalities_geo_simple.json'
'02. us-states.json'
'02. US_Unemployment_Oct2012.csv'
'02. 서울특별시 동작구_주택유형별 위치 정보 및 세대수 현황_20210825.csv'
folium.html
sample_data
m = folium.Map(
location=[37.43087134,127.0233423],
zoom_start=14, # 0-18정도로
tiles="Stamen WaterColor"
)
m
- tiles 종류
https://deparkes.co.uk/2016/06/10/folium-map-tiles/ 참고- folium.Marker()
- 지도에 마커 생성
- folium.Icon()
m = folium.Map(
location=[37.43087134,127.023342], #대공원
zoom_start=14, # 0-18정도로
tiles="OpenStreetMap"
)
# icon basic
folium.Marker(
(37.43564921,127.00594648),
icon=folium.Icon(color="black", icon="info-sign")
).add_to(m) #대공원역
#icon icon_color
folium.Marker(
location=[37.43087134,127.023342], #대공원
popup="<b>LandMark</b>",#볼드체
icon=folium.Icon(
color="red",
icon_color="pink",
icon="cloud"
)
).add_to(m)
#tooltip
folium.Marker(
location=[37.43087134,127.023342], #대공원
popup="<b>LandMark</b>",#볼드체
tooltip="<i>서울대공원</i>" #이탈리아체
).add_to(m)
# html
folium.Marker(
location=[37.43438407,127.00991914], #대공원
popup="<a href='https://zero-base.co.kr/' target=_'blink'>제로베이스</a>",
tooltip="<i>광장</i>"
).add_to(m)
#Icon custom
folium.Marker(
location=[37.43819238,127.00545875], #과천과학박물관
popup="과천과학박물관",
tooltip="Icon custom",
icon=folium.Icon(
color="purple",
icon_color="green",
icon="android",
angle=50, #아이콘의 기울어진 각도
prefix="fa") # "android"같은 경우, prefix="fa" 설정
).add_to(m)
m
m = folium.Map(
location=[37.43087134,127.023342], #대공원
zoom_start=14,
tiles="OpenStreetMap"
)
m.add_child(folium.ClickForMarker(popup="ClickForMarker"))
from folium.features import LatLngPopup
m = folium.Map(
location=[37.43087134,127.023342], #대공원
zoom_start=14,
tiles="OpenStreetMap"
)
m.add_child(folium.LatLngPopup())
m = folium.Map(
location=[37.43087134,127.023342], #대공원
zoom_start=14,
tiles="OpenStreetMap"
)
# Circle
folium.Circle(
location=[37.43200661,127.01796124], #국립현대미술관
radius=100,
fill=True,
color="#5934eb",
fill_color="red",
popup="Circle Popup",
tooltip="Circle Tooltip"
).add_to(m)
# CircleMarker
folium.CircleMarker(
location=[37.42935359,127.02267355], #캠핑장
radius=30,
fill=True,
color="#5934eb",
fill_color="red",
popup="CircleMarker Popup",
tooltip="CircleMarker Tooltip"
).add_to(m)
m
#둘이 별로 차이가 없으니 필요한 것을 사용하면 된다.
import json
state_data = pd.read_csv("02. US_Unemployment_Oct2012.csv")
state_data.head(2)
m = folium.Map([43, -102], zoom_start=3)
folium.Choropleth(
geo_data="02. us-states.json", #경계선 죄표값이 담긴 데이터
data=state_data, #Series or DataFrame
columns=["State", "Unemployment"],
key_on="feature.id",
fill_color="BuPu",
fill_opacity=1, #0-1
line_opacity=1, #0-1
legend_name="Unemployment rate (%)"
).add_to(m)
m
참고
import json
import folium
import pandas as pd
import numpy as np
geo_path = "02. skorea_municipalities_geo_simple.json"
geo_str = json.load(open(geo_path, encoding="utf-8"))
crime_anal_norm = pd.read_csv("02. crime_in_Seoul_final.csv", index_col=0, encoding="utf-8")
crime_anal_norm.tail(2)
# 살인발생 건수 지도 시각화
my_map = folium.Map(
location=[37.5502, 126.982],
zoom_start=11,
tiles="Stamen Toner"
)
folium.Choropleth(
geo_data=geo_str, #우리나라 경계선 좌표값이 담긴 데이터
data=crime_anal_norm["살인"],
columns=[crime_anal_norm.index, crime_anal_norm["살인"]],
key_on="feature.id",
fill_color="PuRd",
fill_opacity=0.7,
line_opacity=0.2,
legend_name="정규화된 살인 발생 건수"
).add_to(my_map)
my_map
# 인구대비 범죄 발생 건수
tmp_criminal = crime_anal_norm["범죄"] / crime_anal_norm["인구수"]
my_map = folium.Map(
location=[37.5502, 126.982],
zoom_start=11,
tiles="Stamen Toner"
)
folium.Choropleth(
geo_data=geo_str, #우리나라 경계선 좌표값이 담긴 데이터
data=tmp_criminal,
columns=[crime_anal_norm.index, tmp_criminal],
key_on="feature.id",
fill_color="PuRd",
fill_opacity=0.7,
line_opacity=0.2,
legend_name="인구 대비 범죄 발생 건수"
).add_to(my_map)
my_map