본문 바로가기
study/Python

[Python] 44. drink.csv 파일 분석하기. annotate, CCTV_in_Seoul.csv, population_in_Seoul.xls 파일 분석하기, crime_in_Seoul.csv, 경찰관서 위치.csv 파일 분석하기

by 금이패런츠 2022. 7. 5.
728x90
반응형

1. drink.csv 파일 분석하기. annotate

2. CCTV_in_Seoul.csv, population_in_Seoul.xls 파일 분석하기

3. crime_in_Seoul.csv, 경찰관서 위치.csv 파일 분석하기

# -*- coding: utf-8 -*-
"""
Created on Tue Jul  5 09:06:50 2022

@author: p011v
"""
########## 1. drink.csv 파일 분석하기. annotate
import pandas as pd
drinks = pd.read_csv("data/drinks.csv")
drinks.info()
# total_servings : 주류소비량 컬럼 추가
drinks["total_servings"] = \
    drinks["beer_servings"] +drinks["spirit_servings"] + drinks["wine_servings"]
drinks.info()
drinks.head()
# alcohol_rate : 알콜비율 (알콜섭취량/전체주류소비량)
drinks["alcohol_rate"] = drinks["total_litres_of_pure_alcohol"]/drinks["total_servings"]
drinks.info()
# alcohol_rate 컬럼의 값이 결측값 : drinks["total_servings"]이 0인 경우 불능 => 결측값
# drinks 데이터중 alcohol_rate 컬럼이 결측값인 레코드
drinks[drinks['alcohol_rate'].isnull()]
# alcohol_rate컬럼이 결측값인 경우 0으로 채우기
drinks['alcohol_rate'] = drinks['alcohol_rate'].fillna(0)
drinks.info()
# drinks 데이터의 country, alcohol_rate 컬럼만을 가지는 데이터 country_alcohol_rank에 저장
country_alcohol_rank = drinks[["country", "alcohol_rate"]]
country_alcohol_rank
# country_alcohol_rank 알콜 비율의 내림차순으로 정렬
country_alcohol_rank = country_alcohol_rank.sort_values(by=["alcohol_rate"], ascending=False)
country_alcohol_rank
country_alcohol_rank.head()
country_alcohol_rank.tail()
# South Korea의 위치값 출력하기
country_alcohol_rank.head(20)
country_alcohol_rank.country.tolist().index("South Korea") #14. 15번째로 알콜비율이 높다.

import numpy as np
import matplotlib.pyplot as plt
plt.rc('font', family = 'Malgun Gothic')
country_list = country_alcohol_rank.country.tolist() # 국가명
print(country_list[:20])
x_pos = np.arange(len(country_list)) # 0 ~ 192. x축값 초기화
rank = country_alcohol_rank.alcohol_rate.tolist() # 알콜량
# bar_list : 막대그래프의 목록
bar_list = plt.bar(x_pos, rank) # 막대그래프 출력 x축 : 0 ~ 192, y축 : 알콜비율
# 대한민국의 막대를 찾아서 빨강색으로 변경
bar_list[country_list.index("South Korea")].set_color('r')
plt.ylabel('alcohol rate')
plt.title('liquor drink rank by country')
plt.axis([0, 200, 0, 0.3]) #(x축시작, x축종료, y축시작, y축종료)
# 대한민국의 인덱스. 대한민국의 x축값
korea_rank = country_list.index("South Korea")
# 대한민국의 알콜비율. 대한민국의 y축값
korea_alc_rate = country_alcohol_rank[country_alcohol_rank['country'] == 'South Korea']\
    ['alcohol_rate'].values[0]
korea_alc_rate
# annotate : 그래프에 설명선 추가
plt.annotate('South Korea : ' + str(korea_rank + 1) + "번째",   # 설명문
             xy = (korea_rank, korea_alc_rate),                 # x, y축 설정
             xytext = (korea_rank + 10, korea_alc_rate + 0.05), #설명문장 시작점
                       arrowprops = dict(facecolor='red', shrink=0.05)) #화살표. 색상:빨강,
plt.show()

'''
    total_servings 전체 술소비량을 막대그래프로 작성하고,
     대한민국의 위치를 빨강색으로 표시하기
     1.country_serving_rank = drinks[["country","total_servings"]]
     2.country_serving_rank total_servings 값의 내림차순으로 정렬 
     3.country_serving_rank 데이터를 막대그래프로 작성.
       대한민국의 데이터는 빨강색으로 변경
     4.막대그래프에 설명선 추가하기  
'''
# 1.country_serving_rank = drinks[["country","total_servings"]]
country_serving_rank = drinks[['country', 'total_servings']]
# 2.country_serving_rank total_servings 값의 내림차순으로 정렬 
country_serving_rank = country_serving_rank.sort_values\
                    (by=['total_servings'], ascending=False)
country_serving_rank.head()
country_list = country_serving_rank.country.tolist() # 국가명
country_list
x_pos = np.arange(len(country_list)) # 0 ~ 192. x축값 초기화
x_pos
rank = country_serving_rank.total_servings.tolist() # 알콜량
# bar_list : 막대그래프의 목록
# 3.country_serving_rank 데이터를 막대그래프로 작성.
# 대한민국의 데이터는 빨강색으로 변경
bar_lit = plt.bar(x_pos, rank) # 막대그래프 출력 x축 : 0 ~ 192, y축 : 알콜비율
# 한국에 해당되는 막대그래프의 색을 빨강색으로 변경
korea_rank = country_list.index("South Korea") #대한민국의 인덱스
print(korea_rank)
bar_list[korea_rank].set_color('r')
plt.ylabel('total_servings')
plt.title('drink servings rank by country')
plt.axis([0, 200, 0, 700]) #(x축시작, x축종료, y축시작, y축종료)
country_serving_rank[country_serving_rank['country'] == 'South Korea']\
    ['total_servings']
#korea_serving_rate : 대한민국의 술소비량
korea_serving_rate = country_serving_rank\
    [country_serving_rank['country'] == 'South Korea']\
        ['total_servings'].values[0]
korea_serving_rate
# 4.막대그래프에 설명선 추가하기  
plt.annotate('South Korea : ' + str(korea_rank + 1) + "번째",   # 설명문
             xy = (korea_rank, korea_serving_rate),                 # x, y축 설정
             xytext = (korea_rank + 10, korea_alc_rate + 50), #설명문장 시작점
             arrowprops = dict(facecolor='red', shrink=50))   #화살표. 색상:빨강,
plt.show()


########## 2. CCTV_in_Seoul.csv, population_in_Seoul.xls 파일 분석하기.
'''
    서울시 각 구별 CCTV수를 파악하고, 인구대비 CCTV 비율을 파악해서 순위 비교
    서울시 각 구별 CCTV수 : 01. CCTV_in_Seoul.csv
    서울시 인구 현황      : 01. population_in_Seoul.xls
'''
import pandas as pd
CCTV_Seoul = pd.read_csv("data/01. CCTV_in_Seoul.csv")
CCTV_Seoul.info()

Pop_Seoul = pd.read_excel("data/01. population_in_Seoul.xls")
Pop_Seoul.info()
Pop_Seoul.head()
'''
    header 정보 : 3번째행. 2번인덱스
    셀데이터 : B, D, G, J, N
'''
Pop_Seoul = pd.read_excel("data/01. population_in_Seoul.xls", header=2,
                          usecols="B, D, G, J, N")
Pop_Seoul.info()
Pop_Seoul.head()

# 컬럼명 변경하기
# CCTV_Seoul : 기관명->구별
CCTV_Seoul.rename(columns={"기관명":"구별"}, inplace=True)
CCTV_Seoul.info()
# Pop_Seoul : 자치구->구별, 계->인구수, 계.1->한국인, 계.2->외국인, 65세이상고령자->고령자
Pop_Seoul.columns=["구별", "인구수", "한국인", "외국인", "고령자"]
Pop_Seoul.info()
Pop_Seoul.head()
# Pop_Seoul 데이터의 첫번째 행을 제거하기
Pop_Seoul.drop([0], inplace=True, axis=0)
Pop_Seoul.head()
'''
    CCTV 최근증가율이 높은 구 5개를 조회하기
    1. 최근증가율 컬럼 추가
        (2014 ~ 2016까지의 최근 3년간 CCTV수의 합) / (2013년도 CCTV수) * 100
    2. 최근증가율 컬럼으로 내림차순 정렬하여 상위 5개 조회.
'''
CCTV_Seoul["최근증가율"] = \
    (CCTV_Seoul["2014년"] + CCTV_Seoul["2015년"] + CCTV_Seoul["2016년"])\
        / CCTV_Seoul["2013년도 이전"] * 100
CCTV_Seoul.info()
CCTV_Seoul.sort_values(by="최근증가율", ascending=False).head()
'''
    외국인비율, 고령자비율이 높은 구 5개 조회하기
    1. Pop_Seoul 데이터의 외국인비율, 고령자비율 컬럼 추가하기
        외국인비율 : 외국인 / 인구수 * 100
        고령자비율 : 고령자 / 인구수 * 100
    2. 외국인비율, 고령자비율로 내림차순 정렬하여 상위 5개 조회.
'''
Pop_Seoul["외국인비율"] = Pop_Seoul["외국인"] / Pop_Seoul["인구수"] * 100
Pop_Seoul["고령자비율"] = Pop_Seoul["고령자"] / Pop_Seoul["인구수"] * 100
Pop_Seoul.info()
Pop_Seoul.sort_values(by="외국인비율", ascending=False).head()
Pop_Seoul.sort_values(by="고령자비율", ascending=False).head()

# 구별 컬럼을 연결 컬럼으로 CCTV 데이터와 인구 데이터 합치기
data_result = pd.merge(CCTV_Seoul, Pop_Seoul, on="구별")
data_result.info()
data_result.head()
# data_result : 2013년도 이전, 2014년, 2015년, 2016년 컬럼제거
# del 명령으로 컬럼 제거
del data_result["2013년도 이전"], data_result["2014년"], \
    data_result["2015년도 이전"], data_result["2016"]
data_result.drop(["2013년도 이전", "2014년", "2015년", "2016년"], inplace=True, axis=1)
# drop함수로 컬럼 제거
data_result.info()
data_result.head()

# data_result 구별컬럼을 인덱스 변경하기
data_result.set_index("구별", inplace=True)
data_result.info()
data_result.head()

# 인구수와 소계 컬럼과의 상관계수 구하기
data_result[["인구수", "소계"]].corr()
import seaborn as sns
sns.pairplot(data_result[["인구수", "소계"]])
sns.regplot(x="인구수", y="소계", data=data_result)
'''
    CCTV 비율 : 인구수대비 CCTV갯수 = CCTV갯수 / 인구수 * 100
    CCTV 비율 컬럼 추가하기
'''
data_result["CCTV비율"] = data_result["소계"] / data_result["인구수"] * 100
data_result.head()

# CCTV의 비율을 수평 막대그래프로 출력하기
data_result["CCTV비율"].sort_values().plot \
    (kind="barh", grid=True, figsize=(10, 10))

# 인구수와 소계의 산점도를 matplot모듈을 이용하여 출력하기
plt.figure(figsize=(6,6))
plt.scatter(data_result["인구수"], data_result["소계"], s=50)
plt.xlabel("인구수")
plt.ylabel("CCTV갯수")
plt.grid()
plt.show()
# 인구수와 소계 데이터의 산점도, 회귀선 출력하기
import numpy as np
# polyfit : 수학적 함수. 방정식 상수값 리턴
#           모든 점과의 차이가 가장 적은 직선의 상수값을 리턴
# 1차식 : ax + b. a:기울기, b:y절편. 직선. 1차함수
# 2차식 : ax**2 + bx + c, 곡선. 2차함수
fp1 = np.polyfit(data_result['인구수'], data_result['소계'], 1) #기울기, y절편 상수 리턴
fp1
# y = f1(fx) : 기대 CCTV 갯수
f1 = np.poly1d(fp1) # ax + b 함수
fx = np.linspace(100000, 700000, 100) # x축의값. 100000 ~ 700000의 값을 100개로 균등분할
plt.Figure(figsize=(6, 6))
plt.scatter(data_result["인구수"], data_result["소계"], s=50) # 산점도
# fx : x축의값
# f1(fx) : x축의 값의 대비 결과값. y축의값
# ls='dashed' : 선의 종류. 댓쉬선.
# lw=3 : 선의 두께
# color='g' : green 색 설정
plt.plot(fx, f1(fx), ls='dashed', lw=3, color='g') # 직선
plt.xlabel("인구수")
plt.ylabel("CCTV갯수")
plt.grid()
plt.show()

# 오차 컬럼 생성하기 : |실제CCTV갯수 - 기대CCTV갯수|
# np.abs : 절대값 함수
# data_result["소계"] : 실제 CCTV 갯수
# f1(data_result["인구수"]) : 기대 CCTV 갯수
data_result["오차"] = np.abs(data_result["소계"], f1(data_result["인구수"]))
data_result["오차"].head()
# 오차가 가장 큰 순으로 정렬하기
df_sort = data_result.sort_values(by="오차", ascending=False)
df_sort
# 산점도, 회귀선을 이용하여 오차가 큰 구를 표시하기
plt.Figure(figsize=(10, 10)) # 그래프 크기 지정
# plt.scatter : 산점도
# x축의값 : data_result['인구수]
# y축의값 : data_result['소계'].CCTV갯수
# c=data_result['오차'] : 색상표. 오차값에 따라서 색상이 달라짐
# s=점크기
plt.scatter(data_result["인구수"], data_result["소계"], 
            c=data_result['오차'], s=50) # 산점도
plt.plot(fx, f1(fx), ls='dashed', lw=3, color='g') # 회귀선
#plt.text: 문자 출력
#df_sort['인구수'][n]*1.02: 글자를 출력할 x축 좌표값
#df_sort['소계'][n]*0.98: 글자를 출력할 y축 좌표값
#df_sort.index[n]: 출력할 텍스트 값
# 오차의 값이 큰 10개의 구정보의 구이름을 출력
for n in range(10) :
    plt.text(df_sort['인구수'][n]*1.02, df_sort['소계'][n]*0.98,
             df_sort.index[n], fontsize=10)
df_sort['인구수'][0]
df_sort.index[0]
plt.xlabel("인구수")
plt.ylabel("CCTV갯수")
plt.colorbar()
plt.grid()
plt.show()

########## 3. crime_in_Seoul.csv, 경찰관서 위치.csv 파일 분석하기.

# 서울시에 있는 경찰서별 범죄율 데이터와 경찰서 위치데이터 읽기
import numpy as np
import pandas as pd
crime_Seoul = pd.read_csv("data/02. crime_in_Seoul.csv",
                          thousands=',', encoding='euc-kr')
crime_Seoul.info()

# 경찰서 위치 데이터 읽기
police_state = pd.read_csv("data/경찰관서 위치.csv", encoding='euc-kr')
police_state.info()

# 지방청 컬럼 값의 종류 출력
police_state["지방청"].unique()

# police_Seoul 데이터에 서울청 데이터만 저장하기
police_state.head()
police_Seoul = police_state[police_state["지방청"] == "서울청"]
police_Seoul.info()
police_Seoul.head()

# police_Seoul 데이터에 경찰서 컬럼 값의 종류 출력하기
police_Seoul["경찰서"].unique() # ex) 서울중부, 서울종로, ...
# crime_Seoul 관서명 컬럼의 종류 출력하기
crime_Seoul["관서명"].unique() # ex) 중부서, 종로서, ...

# police_Seoul 데이터의 경찰서 컬럼의 내용을 xx서로 이름변경하여 
#           관서명 컬럼으로 생성하기
# crime_Seoul 관서명 컬럼과 같은 형식으로 변경하기
police_Seoul["관서명"] = \
    police_Seoul["경찰서"].apply((lambda x : str(x[2:] + '서')))
police_Seoul["관서명"].unique()
crime_Seoul["관서명"].unique()

# 1. police_Seoul 데이터에 지방청, 경찰서, 구분 컬럼 제거하기
del police_Seoul["지방청"], police_Seoul["경찰서"], police_Seoul["구분"]
police_Seoul.info()
# 2. police_Seoul["관서명"] 중복행을 제거하기
police_Seoul = police_Seoul.drop_duplicates(subset=["관서명"])
police_Seoul
police_Seoul.info()
crime_Seoul.info()

# police_Seoul 데이터의 주소 컬럼을 이용하여 구별 컬럼을 생성하기
# police_Seoul 데이터의 주소 컬럼제거하기
police_Seoul["구별"] = police_Seoul["주소"].apply(lambda x : str(x).split()[1])
del police_Seoul["주소"]    
police_Seoul["구별"]    
police_Seoul.info()
crime_Seoul.info()

# 관서명 컬럼을 연결컬럼으로 crime_Seoul 데이터와 police_Seoul 데이터를 병합하기
# data_result 데이터에 저장하기
data_result = pd.merge(crime_Seoul, police_Seoul, on="관서명")
data_result.head()

# 구별 범죄의 합계를 출력하기
crime_sum = data_result.groupby("구별").sum()
crime_sum
# 범죄 종류(강간, 강도, 살인, 절도, 폭력)별 검거율 컬럼 추가하기
# 검거율 = 검거 / 발생 * 100
# 1.
crime_sum["강간검거율]"] = crime_sum["강간 검거"] / crime_sum["강간 발생"] * 100
# 2. 
col_list = ['강간', '강도', '살인', '절도', '폭력']
for col in col_list :
    crime_sum[col + "검거율"] = \
        crime_sum[col + " 검거"] / crime_sum[col + " 발생"] * 100
    print(crime_sum[col + "검거율"].tolist)

crime_sum.info()

# 검거율 데이터중 값이 100보다 큰값은 100으로 변경하기
for col in col_list :
    crime_sum.loc[crime_sum[col + "검거율"] > 100, col + "검거율"] = 100
    
for col in col_list :
    print(crime_sum.loc[crime_sum[col + "검거율"] >= 100, col + "검거율"])

crime_sum['절도검거율'].sort_values() # 절도 검거율 데이터로 오름차순 정렬
# 구별 절도검거율을 수평막대그래프로 출력하기
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.rc('font', family = 'Malgun Gothic')
plt.Figure()
crime_sum['절도검거율'].sort_values().plot \
    (kind='barh', #수평막대그래프. bar : 막대그래프
     grid=True, #배경에 격자무늬
     figsize=(8, 8)) #크기지정
plt.title("서울시 구별 절도 검거율")
plt.show()

drinks.csv
0.00MB
01. CCTV_in_Seoul.csv
0.00MB
01. population_in_Seoul.xls
0.02MB
02. crime_in_Seoul.csv
0.00MB

728x90
반응형