파이썬

 

 

 

 

 

1. 개요

주제 : 한국인 삶의 질 파악
    
데이터 분석 절차

1. 변수(열) 검토 및 전처리 :
    변수의 특징 파악 : 이상치, 결측치 정제 - 분석의 용이성(변수의 값 처리)
    전처리 - 분석할 변수 각각 진행

2. 변수 간 관계 분석 :
    2-1 요약 테이블
    2-2 시각화

 

 

 

2.  모듈 import 및 파일 읽기

1-1. 모듈 import

    sav파일 읽기 : 아나콘다 프롬프트에  pip install pyreadstat 설치 필수

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

 

 

2-1. 파일 읽기 및 복사본 저장

raw_welfare = pd.read_spss('./data/Koweps_hpwc14_2019_beta2.sav')

welfare = raw_welfare.copy()

 

 

3.  데이터 검토

3-1. 데이터 검토

#앞/뒷부분 확인
welfare.head()
welfare.tail()

#행, 열 확인
welfare.shape

#변수 속성 확인
welfare.info()

#요약 통계량 확인
welfare.describe()
'''
             h14_id       h14_ind  ...  h14_pers_income4  h14_pers_income5
count  14418.000000  14418.000000  ...      14418.000000        715.000000
mean    4672.108406      3.121723  ...          2.038702       1183.292308
std     2792.998128      3.297963  ...         32.965477       2147.418274
min        2.000000      1.000000  ...          0.000000     -10600.000000
25%     2356.000000      1.000000  ...          0.000000        206.000000
50%     4535.000000      1.000000  ...          0.000000        530.000000
75%     6616.000000      7.000000  ...          0.000000       1295.000000
max     9800.000000     14.000000  ...       3000.000000      22644.000000

[8 rows x 826 columns]
'''

 

 

3-2. 변수 이름 변경

#성별, 출생년도, 혼인상태, 종교, 수입, 직업코드, 지역코드
welfare = welfare.rename(columns = {'h14_g3' : 'gender',
                                    'h14_g4' : 'birth',
                                    'h14_g10' : 'marriage_type',
                                    'h14_g11' : 'religion',
                                    'p1402_8aq1' : 'income',
                                    'h14_eco9' : 'code_job',
                                    'h14_reg7' : 'code_region'})

 

 

 

4. 분석 및 시각화

4-1. 성별에 따른 월급 차이

1) 성별 변수 검토 및 전처리

#1. 변수 검토 : 타입 파악, 범주 당 인원수
welfare['gender'].dtypes

#2. 빈도 및 이상치 구하기
welfare['gender'].value_counts()

#만일 이상치가 발견됐을 경우, 이상치 결측 처리
welfare['gender'] = np.where(welfare['gender'] == 9, np.nan, welfare['gender'])

#결측치 확인
welfare['gender'].isna().sum()

#결측치 제거 : .dropna()

#성별 항목 이름 부여
welfare['gender'] = np.where(welfare['gender'] == 1, 'male', 'female')
welfare['gender'].value_counts()

 

2) 시각화

sns.countplot(data = welfare, x = 'gender')
plt.show()

 

3)  수입 변수 검토 및 전처리

welfare['income'].dtypes
welfare['income'].describe()



sns.histplot(data = welfare, x = 'income')
plt.show()



#히스토그램이 한쪽으로 치우침
#이상치 확인
welfare['income'].describe()

#결측치 확인
welfare['income'].isna().sum()

 

4) 성별 수입 차이 분석 및 시각화

    성별 수입 평균표 :    gender_income
    income 결측치 제거 :    welfare.dropna(subset = 'income')
    gender별 분리 :    groupby('gender', as_index = False)
    income 평균 산출 :    agg(mean_income = ('income', 'mean'))

gender_income = welfare.dropna(subset = 'income').groupby('gender', as_index = False).agg(mean_income = ('income', 'mean'))



#시각화
sns.barplot(data = gender_income, x = 'gender', y = 'mean_income')
plt.show()

 

 

4-2. 연령별 수입 차이

1) 파생 변수 'age' 선언 :    .assign()

#2019자료이므로 2019만큼 뺀 후 1씩 더하기
welfare = welfare.assign(age = 2019 - welfare['birth'] + 1)
welfare['age'].describe()



sns.histplot(data = welfare, x = 'age')
plt.show()

 

2) 연령별 수입 차이 분석 및 시각화

    나이별 수입 평균표 :    age_income
    income 결측치 제거 :    welfare.dropna(subset = 'income')
    age별 분리 :    groupby('age')
    income 평균 구하기 :    agg(mean_income = ('income', 'mean'))

age_income = welfare.dropna(subset = 'income').groupby('age').agg(mean_income = ('income', 'mean'))



#시각화
sns.lineplot(data = age_income, x = 'age', y = 'mean_income')
plt.show()

 

 

4-3. 연령대별 수입 차이

1) 연령대 변수 선언 :    초년(30세미만) / 중년 / 노년(59세이상) _ .assign()  /  numpy.where()

    np.where(welfare['age'] < 30, 'young', np.where(welfare['age'] <= 59, 'middle', 'old'))

=>  if / elif / else 구조와 같음

welfare['age'].head()

#연령대 변수 선언
welfare = welfare.assign(ageg = np.where(welfare['age'] < 30, 'young', np.where(welfare['age'] <= 59, 'middle', 'old')))

#빈도 산출
welfare['ageg'].value_counts()



#시각화
sns.countplot(data = welfare, x = 'ageg')
plt.show()

 

2) 결측치 제거 후 수입 평균 산출

    연령대별 수입 평균표 :    ageg_income
    income 결측치 제거 :    .dropna(subset = 'income')
    ageg별로 분리 :    .groupby(['ageg'], as_index = False)
    income 평균 구하기 :    .agg(mean_income = ('income', 'mean'))

ageg_income = welfare.dropna(subset = 'income').groupby(['ageg'], as_index = False).agg(mean_income = ('income', 'mean'))

#시각화 1
sns.barplot(data = ageg_income, x = 'ageg', y = 'mean_income')
plt.show()

#시각화 2
sns.barplot(data = ageg_income, x = 'ageg', y = 'mean_income', order = ['young', 'middle', 'old'])
plt.show()

 

 

4-4. 연령대 및 성별 수입 차이

1) 연령대 및 성별 평균표

    성별 항목이 male / female 두개 이므로 hue='gender'

gender_income = welfare.dropna(subset = 'income').groupby(['ageg', 'gender'], as_index = False).agg(mean_income = ('income', 'mean'))



#시각화
sns.barplot(data = gender_income, x = 'ageg', y = 'mean_income', hue = 'gender', order = ['young', 'middle', 'old'])
plt.show()

 

2) 연령 및 성별 수입 차이

gender_age = welfare.dropna(subset = 'income').groupby(['age', 'gender'], as_index = False).agg(mean_income = ('income', 'mean'))

gender_age.head()
'''
    age  gender  mean_income
0  19.0    male   162.000000
1  20.0  female    87.666667
2  20.0    male   155.000000
3  21.0  female   124.000000
4  21.0    male   186.000000
'''



#추세선
sns.lineplot(data = gender_age, x = 'age', y = 'mean_income', hue = 'gender')
plt.show()

3) 결론

    남자는 50세 기준으로 증가치가 급격히 감소, 여자는 30대중반 기준으로 완만하게 감소한다.

성별 수입 차이는 30대 이후로 급격히 벌어짐

 

 

4-5. 직업별 수입 차이

1) 인구 데이터와 직종 분류 데이터 병합

welfare['code_job'].dtypes
welfare['code_job'].value_counts()



#직종 코드 데이터 읽기
list_job = pd.read_excel('./data/Koweps_Codebook_2019.xlsx', sheet_name = '직종코드')
list_job.head()

list_job.shape



#welfare 데이터에 list_job 데이터 결합
welfare = welfare.merge(list_job, how = 'left', on = 'code_job')    #how=어느쪽으로, on=공통키

#code_job 결측치 제거 후, code_job, job 출력
welfare.dropna(subset = 'code_job')[['code_job', 'job']].head()

 

2) 직업별 수입 평균표

job_income = welfare.dropna(subset = ['job', 'income']).groupby('job', as_index = False).agg(mean_income = ('income', 'mean'))



import matplotlib.pyplot as plt
plt.rcParams.update({'font.family' : 'AppleGothic'})

#수입이 많은 직업 상위 10개 시각화
top10 = job_income.sort_values('mean_income', ascending = False).head(10)
sns.barplot(data = top10, y = 'job', x = 'mean_income')
plt.show()

#수입이 적은 직업 하위 10개 시각화
bottom10 = job_income.sort_values('mean_income').head(10)
sns.barplot(data = bottom10, y = 'job', x = 'mean_income').set(xlim = [0, 800])
plt.show()

top10
bottom10

 

 

4-6. 성별 직업 빈도

1) 남성 직업 빈도 상위 10개 추출

#job 결측치 제거
#male 추출 : .query("컬럼이름 == 'male'")
#job별 분리
#job빈도 구하기
#내림차순 정렬
#상위 10행 추출
job_male = welfare.dropna(subset = 'job').query("gender == 'male'").groupby('job', as_index = False).agg(n = ('job', 'count')).sort_values('n', ascending = False).head(10)



#시각화
sns.barplot(data = job_male, y = 'job', x = 'n').set(xlim = [0, 500])
plt.show()

 

2) 여성 직업 빈도 상위 10개 추출

#job 결측치 제거
#female 추출 : .query("컬럼이름 == 'female'")
#job별 분리
#job빈도 구하기
#내림차순 정렬
#상위 10행 추출
job_female = welfare.dropna(subset = 'job').query("gender == 'female'").groupby('job', as_index = False).agg(n = ('job', 'count')).sort_values('n', ascending = False).head(10)



#시각화
sns.barplot(data = job_female, y = 'job', x = 'n').set(xlim = [0, 500])
plt.show()

 

3) 결과

    공통 : 작물재배종사자
    남성 : 자동차운전원 - 경영관련사무원 - 매장판매종사자 순서
    여성 : 청소원및환경미화원 - 매장판매종사자 - 회계및경리사무원 순서

 

4-7. 지역별 연령대 비율

    출생년도를 나이로 환산
    65세 이상만 데이터로 사용
    65세 이상 연령 데이터를 지역별로 연령 분류
    지역별 전체 인구수 대비 노년층 비율

welfare = welfare.assign(code_region = np.where(welfare['code_region'] == 1, '서울', 
                                       np.where(welfare['code_region'] == 2, '수도권(인천/경기)', 
                                       np.where(welfare['code_region'] == 3, '부산/경남/울산', 
                                       np.where(welfare['code_region'] == 4, '대구/경북', 
                                       np.where(welfare['code_region'] == 5, '대전/충남', 
                                       np.where(welfare['code_region'] == 6, '충북/강원', '광주/전남/전북/제주도')))))))

welfare['code_region'].dtypes
welfare['code_region'].value_counts()
welfare['code_region'].shape

welfare.dropna(subset = 'code_region')[['code_region', 'birth']].head()

welfare = welfare.assign(age = 2019 - welfare['birth'] + 1)
welfare['age'].describe()

welfare = welfare.assign(ob = welfare['age'] >= 65)
welfare['ob'].dtypes
welfare['ob'].value_counts()
welfare['ob'].shape

age_ob = welfare.dropna(subset = 'ob').groupby('code_region', as_index = False).agg(mean_ob = ('ob', 'mean'))

top_ob = age_ob.sort_values('mean_ob', ascending = False).head(7)


welfare = welfare.assign(yb = welfare['age'] <= 65)
welfare['yb'].dtypes
welfare['yb'].value_counts()
welfare['yb'].shape

age_yb = welfare.dropna(subset = 'yb').groupby('code_region', as_index = False).agg(mean_yb = ('yb', 'sum'))

pop = age_yb.sort_values('mean_yb', ascending = False).head(7)

 

 

4-8. 종교 유무에 따른 이혼율

1) 종교 데이터 확인

#종교 부분 확인
welfare['religion'].dtypes

#이상치 유무 확인, 두가지 답변이므로 01/02 두 항목만 있어야 함
welfare['religion'].value_counts()

#결측 확인
welfare['religion'].isna().sum()

#01/02를 있다/없다 직관적으로 변경
welfare['religion'] = np.where(welfare['religion'] == 1, 'o', 'x')

#변경 확인
welfare['religion'].value_counts()

 

2) 혼인 데이터 확인

#혼인 부분 확인
welfare['marriage_type'].dtypes

#이상치 유무 확인, 여섯가지 답변이므로 01~06 항목만 있어야 함
welfare['marriage_type'].value_counts()
'''
marriage_type
1.0    7190    결혼
5.0    2357
0.0    2121
2.0    1954
3.0     689    이혼
4.0      78
6.0      29
'''
welfare['marriage_type'].isna().sum()

#이혼 여부를 확인하는 변수 생성
welfare['marriage'] = np.where(welfare['marriage_type'] == 1, 'marriage', np.where(welfare['marriage_type'] == 3, 'divorced', 'etc'))
'''
welfare['marriage']라는 변수를 생성하는데,
np.where(welfare['marriage_type'] == 1, 이라면 'marriage', 를 넣고,
아니라면 np.where(welfare['marriage_type'] == 3, 이라면 'divorced', 를 넣고,
아니라면 'etc'))를 넣고 끝낸다.
'''

 

3) 이혼 여부별 빈도 산출

welfare['marriage'].head()

#새로운 변수 선언해 marriage별 분리
n_divo = welfare.groupby('marriage', as_index = False).agg(n = ('marriage', 'count'))
'''
n = (merriage열을 count한 결과값을 담는)열
'''

#marriage별 빈도 구하기
n_divo.value_counts()

 

4) 종교 유무에 따른 이혼율 분석하기

    etc는 제외한 종교 유무에 따른 이혼율 산출

#religion별 분리해 marriage 추출 후, 비율 구하기
rel_divo = welfare.query('marriage != "etc"').groupby('religion', as_index = False)['marriage'].value_counts(normalize=True)
'''
.query() : 조건을 넣어 데이터를 필터링
.value_counts(normalize=True)로 비율을 구할 수 있음

rel_divo 라는 변수를 생성하는데,
welfare.query('marriage != "etc"')
	: welfare의 marriage열이 "etc"값을 갖지 않은 항목만 필터링해
.groupby('religion', as_index = False)['marriage']
	: marriage열을 religion열 기준으로 그룹화 할 것 index는 고려하지 않고
.value_counts(normalize=True)
	: rel_divo 값을 비율을 산출한다.
'''

#위 결과 divorced추출 후, 소숫점은 반올림해 백분율로 바꾸기
rel_divo = rel_divo.query('marriage == "divorced"').assign(proportion = rel_divo['proportion'] * 100).round(1)
'''
.round(1) : 소숫점 한자리까지만 남김

rel_divo는 rel_divo인데
.query('marriage == "divorced"')
	: marriage열이 "divorced"값을 가진 항목만 필터링해
.assign(proportion = rel_divo['proportion'] * 100)
	: proportion열을 새로 만들 건데 그 값은 rel_divo의 proportion열의 값에 100을 곱하고
.round(1)
	: 소숫점 한자리까지만 남긴 값이다.
'''

 

5) 결론

    비교 결과 수치 상 유의미한 연관성은 발견되지 않음

 

 

4-9. 연령대별 종교 유무에 따른 이혼율

1) etc를 제외한 연령별 이혼율 변수 생성

#ageg별로 분리해 marriage 추출 후, 비율 구하기
age_div = welfare.query('ageg != "young" | marriage == "divored"').groupby('ageg', as_index = False)['marriage'].value_counts(normalize=True)



#초년층 제외한 이혼 추출 후, 백분율로 변경 후 반올림
age_div = age_div.query('marriage == "divorced"').assign(proportion = age_div['proportion'] * 100).round(1)



#etc와 초년층을 제외한 연령대별 종교 유무에 따른 이혼율을 marriage열로 추출 후, 비율 구하기
age_rel_div = welfare.query('marriage != "etc" | ageg != "young"').groupby(['ageg', 'religion'], as_index = False)['marriage'].value_counts(normalize=True)

#divorced 추출 후 백분율로 바꾸고 반올림
age_rel_div = rel_divo.query('marriage == "divorced"').assign(proportion = age_rel_div['proportion'] * 100).round(1)

 

2) 결론

유의미하게 종교가 있는 사람 중 이혼율이 더 낮게 집계됨

 

 

4-9-1. 지역별 연령대 비율

1)  지역 변수 검토 및 전처리

    지역명을 코드값에서 이름으로 변수 추가
    지역별 연령대 비율로 비율표 생성


welfare['code_region'].dtypes
#이상치 유무 확인
welfare['code_region'].value_counts()

welfare['code_region'].isna().sum()

#코드값인 지역명을 codebook상의 지역명으로 변경
list_region = pd.DataFrame({'code_region' : [1, 2, 3, 4, 5, 6, 7],
                            'region' : ['서울', '수도권', '경남', '경북', '충남', '충북/강원', '전라/제주도']})

#지역변수명 추가
welfare = welfare.merge(list_region, how = 'left', on = 'code_region')
welfare['region']

#지역별 연령대 비율로 비율표 생성
#region별 분리하여 ageg 추출
#비율 구하기
region_ageg = welfare.groupby('region', as_index=False)['ageg'].value_counts(normalize=True)

#백분율로
region_ageg = region_ageg.assign(proportion = region_ageg['proportion'] * 100).round(1)

plt.rcParams['font.family'] = 'AppleGothic'  # 맥북 기본 한글 폰트
plt.rcParams['axes.unicode_minus'] = False   # 마이너스 부호 깨짐 방지
sns.barplot(data = region_ageg, y = 'region', x = 'proportion', hue = 'ageg')
plt.show()

 

2)  pivot  생성

    표의 행렬을 뒤바꿔 구성 변경

    누적그래프로 시각화 시 사용


2-1) 지역, 연령대, 비율을 추출
    region_ageg[['region', 'ageg', 'proportion']]

2-2) DataFrame.pivot()
    2-1. 지역을 기준으로 : index=지역
    2-2. 연령대별로 컬럼 구성 : columns = 연령대
    2-3. 각 항목의 값을 비율로 채우기 : values = 비율

pivot_df = region_ageg[['region', 'ageg', 'proportion']].pivot(index = 'region', columns = 'ageg', values = 'proportion')

pivot_df.plot.barh(stacked = True)     #.barh(stacked = True) barh형태로 쌓아라stacked
plt.show()

#노년이 보기 쉽게 컬럼 위치 변경하기
reorder_df = pivot_df.sort_values('old')[['young', 'middle', 'old']]

reorder_df.plot.barh(stacked = True)
plt.show()

 

 

 

 

 

 

파이썬

 

 

 

 

 

1.  모듈 import 및 데이터 추출, 시각화

import pandas as pd
import matplotlib.pyplot as plt

plt.rcParams['font.family'] = 'AppleGothic'
myframe = pd.read_csv('./data/allStoreModified.csv', index_col=0, encoding='utf-8')



print(myframe['brand'].unique())

#한글화
brand_dict = {'cheogajip':'처가집', 'goobne':'굽네',
              'nene':'네네', 'pelicana':'페리카나'}

mygrouping = myframe.groupby(['brand'])['brand']
chartData = mygrouping.count()

newindex = [brand_dict[idx] for idx in chartData.index]

chartData.index = newindex



mycolor = ['r', 'g', 'b', 'm']
plt.figure()
chartData.plot(kind = 'pie',
               legend = False,
               autopct = '%1.2f%%',
               colors = mycolor)

filename = 'myChickenGragh01.png'
plt.savefig(filename, dpi=400, bbox_inches='tight')
print(filename + '이(가) 저장되었습니다!')
plt.show()

 

 

 

 

 

 

 

 

파이썬

 

 

 

 

 

1.  모듈 import 및 데이터 추출, 시각화

import csv
import matplotlib.pyplot as plt

f = open('./data/gender.csv', 'r', encoding='cp949')
data = csv.reader(f)



m = []     #3:104 _ csv 상 데이터의 분포
f = []     #106: _ csv 상 데이터의 분포

name = input('찾을 지역을 입력하세요! _ ').strip()

for row in data :
    if '신도림' in row[0] :
        for i in row[3:104] :
#0기준으로 봤을 때 m의 자료가 왼쪽으로 위치한다고 하면, 모든 자료는 -int
            m.append(-int(i))

        for i in row[106:] :
            f.append(int(i))

print(len(m), len(f))     #808 808



plt.style.use('ggplot')
plt.figure(figsize=(10, 5), dpi=300)
plt.rc('font', family='AppleGothic')
plt.rcParams['axes.unicode_minus']=False     #-값 부분이 손상됨을 방지
plt.title('지역의 남녀 성별 인구 분포')
plt.barh(range(808), m, label='남자')     #range는 위 len() 값과 일치해야 실행됨
plt.barh(range(808), f, label='여자')
plt.legend()
plt.title(name + ' 지역의 남녀 성별 인구 분포')
plt.show()

 

 

 

2.  파이차트를 이용한 시각화

2-1. 파이차트 :    .pie()

    전체 데이터 중 특정 데이터의 비율을 파이 형태로 표현

plt.pie([10, 20])
plt.show()

 

size = [2441, 2312, 1031, 1233]
label = ['A형', 'B형', 'AB형', '0형']
color = ['r', 'g', 'b', 'y']



plt.axis('equal')
plt.rc('font', family='AppleGothic')
plt.pie(size,
        labels=label,
        autopct='%.1f%%',    #'%.1f%%' : 소숫점 이하 1자리
        colors=color,
        explode=(0, 0.1, 0, 0))     #explode=() : 조각 띄우기
plt.legend()
plt.show()

 

 

2-2. 파이차트로 성별 분포 시각화

f = open('./data/gender.csv', 'r', encoding='cp949')
data = csv.reader(f)



name = input('찾을 지역을 입력하세요!_')
size = []      #남자 /여자

for row in data:
    if name in row[0]:
        m = 0
        f = 0
        for i in range(101):
            m += int(row[i+3])
            f += int(row[i+106])
        break     #101개까지만 누적시키기 위함

size.append(m)
size.append(f)



color = ['r', 'g']
label = ['남', '여']

plt.axis('equal')
plt.rc('font', family='AppleGothic')
plt.pie(size,
        labels=label, 
        autopct='%.1f%%',
        colors=color,
        startangle=90)     #startangle=90은 12시방향부터 시작
plt.legend()
plt.title(name + ' 지역의 남녀 성별 인구 분포')
plt.show()

 

 

 

3. 산점도 :    .scatter()

    점이 흩어진 모양의 그래프로 x축과 y축 데이터의 상관 관계 표현하고, 두개의 축 기준으로 데이터의 분포, 산포도 표현

x = [1, 2, 3, 4]
y = [10, 20, 30, 40]
color = ['r', 'g', 'b', 'y']     #list 갯수와 일치

plt.style.use('ggplot')
plt.scatter(x, y)
plt.show()

 

x = [1, 2, 3, 4]
y = [10, 20, 30, 40]
size = [100, 25, 200, 180]     #list 갯수와 일치

plt.style.use('ggplot')
plt.scatter(x, y, s=size, c=range(4), cmap='jet')
plt.colorbar()
plt.show()

 

 

3-1. 산점도로 특정 지역의 인구 분포 시각화

f = open('./data/gender.csv', 'r', encoding='cp949')
data = csv.reader(f)



m = []
f = []

name = input('찾을 지역(도)을 입력하세요!_').strip

for row in data :
    if name in row[0] :
        for i in range(3, 104) :
            m.append(int(row[i]))
            f.append(int(row[i+103]))
        break



plt.style.use('ggplot')
plt.scatter(m, f, c=range(101), cmap='jet', alpha=0.5)     #alpha: 투명도
plt.colorbar()
plt.title(name + ' 지역 성별 인구 분포')
plt.show()

 

 

3-2. 추세선 :    .plot()

    남성 인구 수 중 가장 큰 값을 기준으로 y = x형태의 직선 삽입

f = open('./data/gender.csv', 'r', encoding='cp949')
data = csv.reader(f)



m = []
f = []

name = input('찾을 지역(도)을 입력하세요!_').strip

for row in data :
    if name in row[0] :
        for i in range(3, 104) :
            m.append(int(row[i]))
            f.append(int(row[i+103]))
        break



plt.style.use('ggplot')
plt.rc('font', family='AppleGothic')
plt.scatter(m, f, c=range(101), cmap='jet', alpha=0.5)
plt.colorbar()

#추세선
plt.plot(range(max(m)), range(max(m)), 'g')
plt.title(name + ' 지역 성별 인구 분포')
plt.show()

 

 

 

 

 

파이썬

 

 

 

 

 

1.  개요

    우리 동네 인구 파악 시각화 : 
    
1. 모듈 import 및 파일 읽기

2. 전체 데이터에서 한 줄 씩 반복해 읽기 :  for문

3. 특정 지역의 데이터 확인 : if문

4. 특정 지역에 해당할 경우 인구 수를 0세부터 차례로 저장 : for문, append

5. 저장된 연령 별 인구수 데이터 시각화

 

 

 

2.  데이터 추출 및 시각화

import csv
import matplotlib.pyplot as plt

f = open('./data/age.csv', 'r', encoding='cp949')
data = csv.reader(f)



result = []
for row in data :
    if '신도림' in row[0] :
        for i in row[3:] :
            result.append(int(i))



plt.style.use('ggplot')
plt.plot(result)
plt.show()

 

 

 

3.  input함수 이용하기

f = open('./data/age.csv', 'r', encoding='cp949')
data = csv.reader(f)



result = []
name = input('인구구조가 알고 싶은 지역의 이름(읍면동 단위)을 입력하세요!').strip()

for row in data :
    if name in row[0] :
        for i in row[3:] :
            result.append(int(i))



plt.style.use('ggplot')
plt.plot(result)
plt.title(name +' 지역의 인구 구조')
plt.show()

 

 

 

4.  결론

    중년층의 인구 분포가 가장 많은 편이다.

 

 

 

 

파이썬

 

 

 

 

 

1.  최고 기온 추출 및 시각화

    .hist() : 자료의 분포 상태를 막대그래프로 표현, 데이터의 빈도에 따라 그래프의 높이 결정

    . boxplot() : 데이터를 박스 형태로 표현. 최댓값, 최솟값, 상위 1/4, 2/4(중앙), 3/4에 위치한 값을 표현한 그래프

 

1-1. 최고 기온 히스토그램과 박스플롯으로 각각 시각화

import csv
import matplotlib.pyplot as plt

f = open('./data/seoul.csv', 'r', encoding='cp949')
data = csv.reader(f)
next(data)

result = []
for row in data :     
    if row[-1] != '' :    #해당 행 -1번째 열에 값이 없는('') 게 아니라면
        result.append(float(row[-1]))



plt.hist(result, bins=100, color='r')     #bins=100 : 100개의 구간으로 나눔
plt.show()



plt.boxplot(result)
plt.show()

 

 

1-2. 1월과 8월 데이터만 히스토그램과 박스플롯으로 각각 시각화

f = open('./data/seoul.csv', 'r', encoding='cp949')
data = csv.reader(f)
next(data)

jan = []
aug = []
for row in data :
    month = row[0].split('-')[1]    #해당 행 0번째 열을 -단위로 나눈 값의 1번째 값 => 월
    
    if row[-1] != '' :
        if month == '01' :    #1월 데이터만 수집
            jan.append(float(row[-1]))
            
    if row[-1] != '' :
        if month == '08' :    #8월 데이터만 수집
            aug.append(float(row[-1]))



plt.hist(jan, bins=100, color='r', label='JAN')
plt.hist(aug, bins=100, color='b', label='AUG')
plt.legend()    #label 사용 시, .legend() 입력
plt.show()



plt.boxplot(jan)
plt.boxplot(aug)
plt.show()

 

 

2. 1월과 8월 최고 기온의 이상치 박스플롯으로 파악

    이상치(outlier) : 다른 수치에 비해 이상적으로 크거나 작은 값을 표현

f = open('./data/seoul.csv', 'r', encoding='cp949')
data = csv.reader(f)
next(data)

jan = []
aug = []
for row in data :
    month = row[0].split('-')[1]
    
    if row[-1] != '' :
        if month == '01' :
            jan.append(float(row[-1]))
            
    if row[-1] != '' :
        if month == '08' :
            aug.append(float(row[-1]))



plt.boxplot([jan, aug])    #두 데이터를 한꺼번에
plt.show()

 

 

 

3. 최고 기온을 월 별로 구분해 박스플롯으로 시각화

    데이터를 월 별로 분류 저장 후, 박스프롯으로 표현

f = open('./data/seoul.csv', 'r', encoding='cp949')
data = csv.reader(f)
next(data)

months = [[], [], [], [], [], [], [], [], [], [], [], []]    #12개월
for row in data :
    if row[-1] != '' :
        months[int(row[0].split('-')[1])-1].append(float(row[-1]))
'''
months[int(row[0].split('-')[1])-1] : 
	날짜를 split해 index로 사용
	월을 추출해 int로 변환 후, -1을 적용해 index가 0부터 시작할 수 있도록 맞춰 줌
'''

plt.boxplot(months)
plt.show()

 

 

 

 

 

파이썬

 

 

 

 

 

1.  결측치

 

1-1. 임의의 결측치 만들기 :    numpy.nan

import pandas as pd
import numpy as np

df = pd.DataFrame({'sex' : ['M', 'F', np.nan, 'M', 'F'],
                   'score' : [5, 4, 3, 4, np.nan]})
print(df)
'''
   sex  score
0    M    5.0
1    F    4.0
2  NaN    3.0
3    M    4.0
4    F    NaN
'''

 

 

1-2. 결측치 확인

#nan은 아예 값이 없는 False 상태이므로 값을 연산할 수 없음
df['score'] + 1
'''
0    6.0
1    5.0
2    4.0
3    5.0
4    NaN
Name: score, dtype: float64
'''



#결측치 여부 파악 : pandas.isna() => True / False
pd.isna(df)
'''
     sex  score
0  False  False
1  False  False
2   True  False
3  False  False
4  False   True
'''



#결측치 갯수 파악
pd.isna(df).sum()
'''
sex      1
score    1
dtype: int64
'''

 

 

1-3. 결측치 제거

    결측치가 있는 모든 행 제거 :    DataFrame.dropna()
    결측치가 있는 특정 행 제거 :    DataFrame.dropna(subset='지정 열')

    inplace=True로 설정해야 원본 데이터에 적용.

df.dropna()
df.dropna(subset = 'score')



#결측치를 자동으로 배제하는 연산 함수1 : mean()  /  sum()
df['score'].mean()
df['score'].sum()



#결측치를 자동으로 배제하는 연산 함수2 : groupby()  /  agg()
#집단(그룹) 별 통계량
df.groupby('sex').agg(mean_score = ('score', 'mean'), sum_score = ('score', 'sum'))
'''
     mean_score  sum_score
sex                       
F           4.0        4.0
M           4.5        9.0
'''

 

 

1-4. 결측치 대체 :    DataFrame.fillna()

exam = pd.read_csv('./data/exam.csv')

#임의의 record에 결측값 삽입
exam['math'].loc[[2, 7, 14]] = np.nan



#특정 열 전체 값의 평균
exam['math'].mean()
'''
55.23529411764706
'''



#해당 열 전체 값 평균으로 결측치 대체
exam['math'] = exam['math'].fillna(55)



#결측 여부 파악 시 결측 없음
exam['math'].isna().sum()
'''
0
'''

 

 

 

2. 이상치 : 존재할 수 없는 값

2-1. 이상치 확인 :    DataFrame.value_counts()

  DataFrame.value_counts()로 각 record의 값이 몇개나 존재하는지, 빈도 파악.

df = pd.DataFrame({'sex' : [1, 2, 1, 3, 2, 1],
                   'score' : [5, 4, 3, 4, 2, 6]})



df['sex'].value_counts(sort = False).sort_index()
'''
sex
1    3
2    2
3    1
Name: count, dtype: int64
'''
 
 
 
df['score'].value_counts(sort = False).sort_index()
'''
score
2    1
3    1
4    2
5    1
6    1
Name: count, dtype: int64
'''

 

 

2-2. 이상치를 결측치로 변경 :    numpy.where()

    if문 대체하여 사용하고, numpy.where()는 문자와 NaN을 함께 반환 못하므로 주의.

    구조 :    numpy.where(특정열의값이어떠하면, 어떤값을, 어떤열에넣음)

#sex가 3이면 NaN 부여
df['sex'] = np.where(df['sex'] == 3, np.nan, df['sex'])
'''
0    1.0
1    2.0
2    1.0
3    NaN
4    2.0
5    1.0
Name: sex, dtype: float64
'''



#score가 5보다 크면 NaN 부여
df['score'] = np.where(df['score'] > 5, np.nan, df['score'])
'''
0    5.0
1    4.0
2    3.0
3    4.0
4    2.0
5    NaN
Name: score, dtype: float64
'''



#sex, score 결측치 제거
#sex 별 분리 및 score 평균 산출
df.dropna().groupby('sex').agg(mean_score = ('score', 'mean'))
df.dropna(subset = ['sex', 'score']).groupby('sex').agg(mean_score = ('score', 'mean'))
'''
     mean_score
sex            
1.0         4.0
2.0         3.0
'''

 

 

2-3. boxplot을 이용한 이상치 확인 및 제거

1) boxplot으로 이상치 확인

mpg = pd.read_csv('./data/mpg.csv')

import matplotlib.pyplot as plt
import seaborn as sns

sns.boxplot(data = mpg, y ='hwy')
plt.show()

    이상치가 상단에 두개의 점으로 표시됨.

 

2) 극단치 산출하여 제거

#극단치 기준값 산출
#1. 1사분위수, 3사분위수 사용
pct25 = mpg['hwy'].quantile(.25)    #18.0
pct75 = mpg['hwy'].quantile(.75)    #27.0

#2. IQR 구하기 : 1사분위수, 3사분위수의 거리
iqr = pct75 - pct25    #9.0

#3. 극단 경계 구하기 : 하한, 상한 구하기
#하한 : 1사분위수 보다 IQR의 1.5배 만큼 더 작은 값
pct25 - 1.5 * iqr    #4.5
#상한 : 3사분위수 보다 IQR의 1.5배 만큼 더 큰 값
pc75 + 1.5 * iqr    #40.5



#극단치 결측으로 처리
mpg['hwy'] = np.where((mpg['hwy'] < 4.5) | (mpg['hwy'] > 40.5), np.nan, mpg['hwy'])
'''
0      29.0
1      29.0
2      31.0
3      30.0
4      26.0

229    28.0
230    29.0
231    26.0
232    26.0
233    26.0
Name: hwy, Length: 234, dtype: float64
'''



#결측치 갯수 파악
mpg['hwy'].isna().sum()
'''
3
'''


#hwy 결측치 제거 : drv별 분리 및 hwy평균 구하기
mpg.dropna(subset='hwy').gorupby('drv').agg('hwy')
'''
      mean_hwy
drv           
4    19.174757
f    27.728155
r    21.000000
'''



sns.boxplot(data = mpg, y ='hwy')
plt.show()

 

 

 

 

파이썬

 

 

 

 

 

1. 그래프 기본 구조

import matplotlib.pyplot as plt

#그래프 기본 구조 생성 : matplotlib.pyplot.figure()
plt.figure()

#기본 구조에 그래프 그리기 : matplotlib.pyplot.plot(시각화 데이터)
plt.plot()

#그래프 출력 : matplotlib.pyplot.show
plt.show()

 

 

 

2. 직선, 꺽은 선 등의 선형 그래프 :    .plot()

2-1. x축과 y축

1) 하나의 데이터를 넣으면 y축

plt.plot([10, 20, 30, 40])
plt.show()

 

2) 두개의 데이터를 넣으면 각각 x축과 y축

plt.plot([10, 20, 30, 40], [9, 4, 56, 7])
plt.show()

 

 

2-2. 두개 이상의 그래프에 범례 설정 :    .plot(x, label='')  /  .plot(y, label=''),    .legend()

#범례 표시 : label='내용'
plt.plot([10, 20, 30, 40], label='asc')
plt.plot([40, 30, 20, 10], label='ascd')
plt.legend()
plt.show()

 

 

2-3. 제목 설정 :    .title('')

plt.title('plotting')
plt.plot([10, 20, 30, 40], label='asc')
plt.plot([40, 30, 20, 10], label='ascd')
plt.legend()
plt.show()

 

 

2-4. 선 색상 설정 :    .plot(x, color='알려진 색상')  /  .plot(y, color='알려진 색상')

plt.title('color')
plt.plot([10, 20, 30, 40], color='skyblue', label='skyblue')     
plt.plot([40, 30, 20, 10], color='pink', label='pink')
plt.legend()
plt.show()

 

 

2-5. 선 형태 변경 :    linestyle = ''  /  ls = ''

plt.title('linestyle')
plt.plot([10, 20, 30, 40], linestyle='--', label='dashed')     
plt.plot([40, 30, 20, 10], ls=':', label='dotted')
plt.legend()
plt.show()

 

 

2-6.  선이 아닌 마크로 형태 변경

plt.title('mark')
plt.plot([10, 20, 30, 40], 'r.', label='circle')     
plt.plot([40, 30, 20, 10], 'g^', label='triangle')
plt.legend()
plt.show()

 

2-7.  선, 색상 스타일 변경 2

t = [0,1,2,3,4,5,6]
y = [6,5,4,3,2,1,0]

#1
plt.figure(figsize=(10, 6))    #figsize=(10, 6)  =>  10:6비율
plt.plot(t, y, color='green')
plt.show()



#2
plt.figure(figsize=(10, 6))
plt.plot(t, y, color='green',
         linestyle='dashed')
plt.show()



#3
plt.figure(figsize=(10, 6))
plt.plot(t, y, color='green',
         linestyle='dashed',
         marker='o')
plt.show()



#4
plt.figure(figsize=(10, 6))
plt.plot(t, y, color='green',
         linestyle='dashed',
         marker='o',
         markerfacecolor='blue')
plt.show()



#5
plt.figure(figsize=(10, 6))
plt.plot(t, y, color='green',
         linestyle='dashed',
         marker='o',
         markerfacecolor='blue',
         markersize=20)
plt.grird()    #grid 삽입
plt.show()

 

 

 

3. 산점도 그래프 :    .scatter()

import numpy as np

t = np.array([0,1,2,3,4,5,6,7,8,9])
y = np.array([9,8,7,8,3,2,4,7,8,0])

plt.figure(figsize=(10, 6))
plt.scatter(t, y)
plt.show()



plt.figure(figsize=(10, 6))
plt.scatter(t, y, marker='>')
plt.show()



plt.figure(figsize=(10, 6))
plt.scatter(t, y, marker='>', s=50)
plt.show()



colormap = t
plt.figure(figsize=(10, 6))
plt.scatter(t, y, marker='>', s=50, c=colormap)
plt.show()



colormap = t
plt.figure(figsize=(10, 6))
plt.scatter(t, y, marker='>',    #마크 모양 변경
				  s=50,    #마커 크기 변경
                  c=colormap)    #색상 삽입
plt.colorbar()    #삽입한 색상에 대한 막대그래프 생성
plt.show()

 

 

 

 

 

파이썬

 

 

 

 

 

1.  개요

국감브리핑을 통해 강남3구의 주민들이 거주지 체감 안전도를 높게 생각한다는 기사 확인
http://news1.kr/articles/?1911504 

분석 내용

1. 서울시 각 자치구 별 CCTV 수 파악
2. 인구 대비 CCTV 비율을 파악해 순위 비교
3. 인구 대비 CCTV의 평균치를 확인 후 CCTV가 가장 부족한 자치구 확인
4. 단순한 그래프 표현에서 한 단계 더 나아가 경향을 확인하고 시각화

 

 

 

2.  모듈 import

conda install -c anaconda xlrd

    모듈 import 전, 아나콘다프롬프트 혹은 spyder 콘솔에 상기 코드를 입력해 모듈이 원활하게 수행되도록 함.

 

#csv, excel 파일 읽기 모듈
import pandas as pd

#숫자 관련 모듈
import numpy as np

#시각화 작업 모듈
import matplotlib.pyplot as plt
from matplotlib import font_manager, rc

#사용 컴퓨터의 운영체제 확인 모듈
import platform

#한글 폰트 손상 방지
plt.rcParams['axes.unicode_minus'] = False

#운영체제에 맞는 기본 폰트 설정
if platform.system() == 'Darwin':     #애플
    rc('font', family='AppleGothic')
elif platform.system() == 'Windows':
    path = 'c:/Windows/Fonts/malgun.ttf'
    font_name = font_manager.FontProperties(fname=path).get_name()
    rc('font', family=font_name)
else:
    print('sorry!')

 

 

 

3.  데이터 읽기

3-1. 서울시 cctv 데이터 읽기 및 정제

1) 파일 읽기 :    pandas.read_csv('파일경로')

CCTV_seoul = pd.read_csv('./cctv/data1/01. CCTV_in_Seoul.csv', encoding='utf-8')

 

2) 열 이름 확인 :    DataFrame.columns / DataFrame.columns[index열]

CCTV_seoul.columns
CCTV_seoul.columns[0]
CCTV_seoul.head()

 

3) index 열 이름 변경 :    DataFrame.rename(columns={DataFrame.columns[index열] : '변경할 이름'}, inplace=True)

CCTV_seoul.rename(columns={CCTV_seoul.columns[0] : '자치구'}, inplace=True)

#변경 여부 확인
CCTV_seoul.columns[0]

    '기관명'이라고 되어 있는 index 열을 '자치구'로 변경,

    inplace를 True로 적용해야 변경사항을 원본 DataFrame에 적용.

 

 

3-2. 서울시 인구 데이터  읽기 및 정제

1) 파일 읽기 :    pandas.read_excel('파일경로')

#전체 읽어 올 경우
pop_Seoul = pd.read_excel('./cctv/data1/01. population_in_Seoul.xls')

#분석에 유의미한 부분만 선택해 읽어 올 경우
#header=엑셀 행(인덱스) 번호 : 엑셀의 첫 몇 줄로 불필요하면 입력한 숫자만큼 건너뜀
#usecols='엑셀 열 이름, 이름....'  /  B:구이름, D:인구수, G:한국인, J:외국인, N:고령자(65세이상)
pop_Seoul = pd.read_excel('./cctv/data1/01. population_in_Seoul.xls',
                          header=2,
                          usecols='B, D, G, J, N')

pop_Seoul.head()

#결과
'''
   자치구           계        계.1       계.2   65세이상고령자
0   합계  10197604.0  9926968.0  270636.0  1321458.0
1  종로구    162820.0   153589.0    9231.0    25425.0
2   중구    133240.0   124312.0    8928.0    20764.0
3  용산구    244203.0   229456.0   14747.0    36231.0
4  성동구    311244.0   303380.0    7864.0    39997.0
'''

 

2) 각 열 이름 변경

#자치구 : 구별, 계 : 인구수, 계1 : 한국인, 계2 : 외국인, 65세이상고령자 : 고령자

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.columns

#결과
'''
Index(['자치구', '인구수', '한국인', '외국인', '고령자'], dtype='object')
'''

 

 

 

4.  데이터 전처리

4-1.  서울시 cctv 데이터 파악

    13년도 이전과 이후 CCTV 증가율을 나타내는 '최근증가율' 열 추가.

CCTV_seoul.head(5)
CCTV_seoul.tail(5)

#DataFrame에 열 추가 : DataFrame['새 열 이름'] = 추가 예정 데이터
#증가율 = (2014년 + 2015년 + 2016년) / 2013년 이전 * 100
CCTV_seoul['최근증가율'] = (CCTV_seoul['2014년']+CCTV_seoul['2015년']+CCTV_seoul['2016년'])/
						 CCTV_seoul['2013년도 이전'] * 100

#결과
'''
0     150.619195
1     166.490765
2     125.203252
3     134.793814
4     149.290780
5      53.228621
6      64.973730
7     100.000000
8     188.929889
9     246.638655
10     74.766355
11    139.338235
12    212.101911
13     48.578199
14     63.371266
15     81.780822
16     63.627354
17    104.347826
18     34.671731
19    157.979798
20     53.216374
21     85.237258
22    248.922414
23    147.699758
24     79.960707
Name: 최근증가율, dtype: float64
'''



CCTV_seoul.sort_values(by='최근증가율', ascending=False).head()

#결과
'''
    자치구    소계  2013년도 이전  2014년  2015년  2016년       최근증가율
22  종로구  1002        464    314    211    630        248.922414
9   도봉구   485        238    159     42    386        246.638655
12  마포구   574        314    118    169    379        212.101911
8   노원구  1265        542     57    451    516        188.929889
1   강동구   773        379     99    155    377        166.490765
'''

 

 

4-2. 서울시 인구 데이터 파악

1) 결측치 확인 및 처리

#결측치 NaN 확인 : isnull()
#유일 값 확인 : unique()
#행 삭제 : drop([행index번호])

#'합계' 행 삭제 : 전체 자치구 값의 합계이므로 불필요
pop_Seoul.drop([0], inplace=True)



#'자치구' 열의 유일 값 확인
pop_Seoul['구별'].unique()

#결과
'''
array(['종로구', '중구', '용산구', '성동구', '광진구', '동대문구', '중랑구', '성북구', '강북구',
       '도봉구', '노원구', '은평구', '서대문구', '마포구', '양천구', '강서구', '구로구', '금천구',
       '영등포구', '동작구', '관악구', '서초구', '강남구', '송파구', '강동구', nan],
      dtype=object)
'''



#'자치구' 열의 결측치 확인
pop_Seoul[pop_Seoul['구별'].isnull()]

#결과
'''
    자치구  인구수  한국인  외국인  고령자
26  NaN  NaN  NaN  NaN  NaN
'''



#결측치 행 삭제 _ 해당 행에서의 결측은 데이터에 크게 영향을 미치지 않음
pop_Seoul.drop([26], inplace=True)
pop_Seoul.tail()

#결과
'''
    자치구       인구수       한국인      외국인      고령자
21  관악구  525515.0  507203.0  18312.0  68082.0
22  서초구  450310.0  445994.0   4316.0  51733.0
23  강남구  570500.0  565550.0   4950.0  63167.0
24  송파구  667483.0  660584.0   6899.0  72506.0
25  강동구  453233.0  449019.0   4214.0  54622.0
'''

 

2) 외국인과 고령자 비율 열 생성

    외국인과 고령자의 비율을 별도의 열을 생성하여 파악.

#'외국인비율' = '외국인' / '인구수' * 100
pop_Seoul['외국인비율'] = pop_Seoul['외국인'] / pop_Seoul['인구수'] * 100

#'고령자비율' = '고령자' / '인구수' * 100
pop_Seoul['고령자비율'] = pop_Seoul['고령자'] / pop_Seoul['인구수'] * 100

#인구수/외국인/외국인비율/고령자/고령자비율을 기준으로 각각 정렬 후 데이터 확인
pop_Seoul.sort_values(by='인구수', ascending=False).head(5)
pop_Seoul.sort_values(by='외국인', ascending=False).head(5)
pop_Seoul.sort_values(by='외국인비율', ascending=False).head(5)
pop_Seoul.sort_values(by='고령자', ascending=False).head(5)
pop_Seoul.sort_values(by='고령자비율', ascending=False).head(5)

#결과
'''
     자치구       인구수       한국인      외국인      고령자     외국인비율      고령자비율
9    강북구  330192.0  326686.0      3506.0     54813.0    1.061806  16.600342
1    종로구  162820.0  153589.0      9231.0     25425.0    5.669451  15.615404
2     중구  133240.0  124312.0      8928.0     20764.0    6.700690  15.583909
3    용산구  244203.0  229456.0     14747.0     36231.0    6.038828  14.836427
13  서대문구  327163.0  314982.0     12181.0     48161.0    3.723221  14.720797
'''

 

 

4-3. CCTV와 인구 데이터 병합 및 정제

1) CCTV와 인구 데이터 병합

    새DataFrame = Pandas.merge(DataFrame1, DataFrame2, on='공통 열')

#Pandas.merge(CCTV_seoul, pop_Seoul, on='공통 열')
#만약 두 프레임의 공통 열이 없다면 : left_on='열', right_on='열'
data_result = pd.merge(CCTV_seoul, pop_Seoul, on='구별')
data_result.head()
data_result.tail()

 

2) 불필요한 열 삭제 :    del DataFrame['열']

#2013년도 이전 / 2014년 / 2015년 / 2016년 : 현재에 해당하는 '소계'만 남기고 삭제
#자치구 / 소계 / 최근증가율 / 인구수 / 한국인 / 외국인 / 고령자 / 외국인비율
del data_result['2013년도 이전']
del data_result['2014년']
del data_result['2015년']
del data_result['2016년']
data_result.head()

#결과
'''
   자치구    소계       최근증가율       인구수  ...      외국인      고령자     외국인비율      고령자비율
0  강남구  2780    150.619195  570500.0  ...       4950.0  63167.0    0.867660  11.072217
1  강동구   773    166.490765  453233.0  ...       4214.0  54622.0    0.929765  12.051638
2  강북구   748    125.203252  330192.0  ...       3506.0  54813.0    1.061806  16.600342
3  강서구   884    134.793814  603772.0  ...       6524.0  72548.0    1.080540  12.015794
4  관악구  1496    149.290780  525515.0  ...      18312.0  68082.0    3.484582  12.955291

[5 rows x 9 columns]
'''

 

3) 분석 및 시각화를 위해 '자치구' 열을 index로 설정

    DataFrame.set_index('index로 사용될 열', inplace=True)

data_result.set_index('자치구', inplace=True)

 

 

 

5.   분석 및 시각화

5-1. 각 데이터 간 연관성 파악을 위해 상관계수 산출 :    Numpy.corrcoef()

#고령자비율과 소계 간 상관 관계
np.corrcoef(data_result['고령자비율'], data_result['소계'])

#결과
'''
array([[ 1.        , -0.28078554],
       [-0.28078554,  1.        ]])
'''



#인구수와 소계 간 상관 관계
np.corrcoef(data_result['인구수'], data_result['소계'])

#결과
'''
array([[1.        , 0.30634228],
       [0.30634228, 1.        ]])
'''

 

 

5-2. 시각화

1) 자치구 및 소계 데이터 시각화

plt.figure()
data_result['소계'].plot(kind='barh',
                       grid=True,
                       figsize=(10, 10))
plt.show()

 

2) 소계를 기준으로 정렬 후 시각화

data_result['소계'].sort_values().plot(kind='barh',
                                     grid=True,
                                     figsize=(10, 10))
plt.show()

 

3) 인구수 대비 CCTV비율 시각화

data_result['CCTV비율'] = data_result['소계'] / data_result['인구수'] * 100

data_result['CCTV비율'].sort_values().plot(kind='barh',
                                         grid=True,
                                         figsize=(10, 10))
plt.show()

 

4) 인구수와 소계에 대한 산점도

plt.figure(figsize=(6, 6))
plt.scatter(data_result['인구수'], data_result['소계'], s=50)  #s:산점도 점 크기
plt.xlabel('인구수')
plt.ylabel('cctv')
plt.grid()
plt.show()

 

5) 인구수와 CCTV비율에 대한 산점도

plt.figure(figsize=(6, 6))
plt.scatter(data_result['인구수'], data_result['CCTV비율'], s=50)
plt.xlabel('인구수')
plt.ylabel('cctv')
plt.grid()
plt.show()

 

6) 인구수와 CCTV비율에 대한 산점도의 선형회귀선    *선형회귀 : 두 변수(열)의 관계

fp1 = np.polyfit(data_result['인구수'], data_result['소계'], 1)
f1 = np.poly1d(fp1)     #직선 만들기
fx = np.linspace(100000, 700000, 100)     #(부터, 까지, 간격)으로 그리기

plt.figure(figsize=(10,10))
plt.scatter(data_result['인구수'], data_result['소계'], s=50)
plt.plot(fx, f1(fx), ls='dashed', lw=3, color='r')    #ls : line style, lw : line width
plt.xlabel('인구수')
plt.ylabel('cctv')
plt.grid()
plt.show()

 

 

 

6. 결론

    서울시 내 강남구, 양천구, 용산구, 서초구, 은평구는 인구 대비 cctv가 많고,
    강서구, 송파구, 도봉구 등은 인구 대비 부족함. 따라서 강남 3구 전체가 안전하다고 판단하기는 어려움.

 

 


7. 시각화 심화하기

7-1. '오차' 산출 :     data_result['소계'] - data_result['인구수']

        절댓값 산출 :    Numpy.abs()

fp1 = np.polyfit(data_result['인구수'], data_result['소계'], 1)
f1 = np.poly1d(fp1)
fx = np.linspace(100000, 700000, 100)

data_result['오차'] = np.abs(data_result['소계'] - f1(data_result['인구수']))

df_sort = data_result.sort_values(by='오차', ascending=False)

 

 

7-2. 시각화

plt.figure(figsize=(14, 10))
plt.scatter(df_sort['인구수'], df_sort['소계'],
            c=data_result['오차'],
            s=50)
plt.plot(fx, f1(fx), ls='dashed', lw=3, color='r')

for n in range(10):
    plt.text(df_sort['인구수'][n]*1.02,     #x좌표
             df_sort['소계'][n]*0.98,     #y좌표
             df_sort.index[n],     #자치구
             fontsize=15)

plt.xlabel('인구수')
plt.ylabel('인구당 비율')
plt.colorbar()
plt.grid()
plt.show()

 

 

 

 

파이썬

 

 

 

 

 

1.  순서

1) 사용 모듈 import 및 데이터 읽기
2) 분석에 사용할 데이터 저장 및 list 선언
3) '일시' 열에서 2020-07-30 부분을 DateTime 형식의 index로 만들어 : DatetimeIndex(DataFrame[기존 열]).새로운열
    DataFrame에 신규컬럼('month')에 추가
4) 월 별로 분리하여 저장 및 테스트
5) 전체 데이터를 이용 1월부터 12월까지의 평균 풍속을 저장
6) matplotlib을 이용한 간단한 시각화

 

 

 

2. 사용 모듈 import 및 데이터 읽기

import pandas as pd
import matplotlib.pyplot as plt

weather = pd.read_csv('./data/csv/weather.csv', encoding='CP949')
weather.head(2)
weather.tail(2)
weather.info()

#결과
'''
           일시  평균기온(°C)  최대 풍속(m/s)  평균 풍속(m/s)
0  2010-08-01      28.7         8.3         3.4
1  2010-08-02      25.2         8.7         3.8

              일시  평균기온(°C)  최대 풍속(m/s)  평균 풍속(m/s)
3651  2020-07-30      22.9         9.7         2.4
3652  2020-07-31      25.7         4.8         2.5

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3653 entries, 0 to 3652
Data columns (total 4 columns):
 #   Column      Non-Null Count  Dtype  
---  ------      --------------  -----  
 0   일시          3653 non-null   object 
 1   평균기온(°C)    3653 non-null   float64
 2   최대 풍속(m/s)  3649 non-null   float64
 3   평균 풍속(m/s)  3647 non-null   float64
dtypes: float64(3), object(1)
memory usage: 114.3+ KB
'''

 

 

 

3. 분석에 사용할 데이터 저장 및 list 선언

    월 별로 구분된 12개의 데이터를 저장할 list와

    월 별로 구분된 12개의 풍속 데이터를 저장할 list 생성

monthly = [0 for x in range(12)]

'''
위 코드는 이것과 같음
monthly_wind = []
for x in range(12) :
    monthly_wind.append(0)
'''



monthly_wind = [0 for x in range(12)]

 

 

4. 새로운 열('month') 추가

    '일시' 열의 2020-07-30 부분을 DateTime형식의 index로 만들어 새로운 열 'month' 생성 및 추가

weather['month'] = pd.DatetimeIndex(weather['일시']).month
weather.head()

#결과
'''
           일시  평균기온(°C)  최대 풍속(m/s)  평균 풍속(m/s)  month
0  2010-08-01      28.7         8.3         3.4      8
1  2010-08-02      25.2         8.7         3.8      8
2  2010-08-03      22.1         6.3         2.9      8
3  2010-08-04      25.3         6.6         4.2      8
4  2010-08-05      27.2         9.1         5.6      8
'''

 

 

 

5. 월 별 저장 및 테스트

#매 해 1월 데이터 추출 및 저장 테스트
monthly[0] = weather[weather['month'] == 1]
monthly[0]['평균 풍속(m/s)'].mean()

#매 해 12월 데이터 추출 및 저장 테스트
monthly[11] = weather[weather['month'] == 12]
monthly[11]['평균 풍속(m/s)'].mean()

 

 

 

6. 전체 데이터의 1월부터 12월까지의 '평균 풍속(m/s)' 저장

    for 반복문을 이용해, monthly_wind에 1부터 12까지의 행을 생성하고 평균 값을 삽입.

for i in range(12):     #i = 0 ~ 11
    monthly[i] = weather[weather['month'] == i+1]    #가장 첫 행은 0번이기 때문에 +1
    monthly_wind[i] = monthly[i]['평균 풍속(m/s)'].mean()
    
#결과
'''
[3.7574193548387096,
 3.946785714285714,
 4.390291262135922,
 4.62248322147651,
 4.219354838709678,
 3.461,
 3.8774193548387097,
 3.5961290322580637,
 3.6616666666666666,
 3.9616129032258067,
 3.930666666666666,
 3.817096774193548]
'''

 

 

 

7. matplotlib을 이용한 간단한 시각화

plt.plot(monthly_wind, 'red')
plt.show()



 

8. 결론

    매 월 평균 풍속은 크게 차이가 없으나, 봄철인 3, 4, 5월에 소폭 상승하는 양상을 보인다.

 

 

 

 

파이썬

 

 

 

 

 

1.  정보 추출 함수

 

1-1. DataFrame의 상/하위 n개 데이터 추출 :    .head() / .tail()

    외부 데이터가 잘 추출됐는지 확인 용도, 기본 값은 5개

df = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=['A', 'B', 'C', 'D'])
df.head()
df.head(3)
df.tail()
df.tail(2)

#결과
'''
                   A         B         C         D
2021-12-08 -1.208131 -2.194505 -0.592236  0.080834
2021-12-09 -1.195402 -0.327135 -1.630431  1.326106
2021-12-10  0.111884  3.096611 -0.282745  0.513996
2021-12-11  1.032994 -1.051557  1.020307  1.172119
2021-12-12  0.223649  0.167089 -0.991968  1.080597

.
.
.
'''




1-2. DataFrame의 index 추출 :    .index

df.index

#결과
'''
DatetimeIndex(['2021-12-08', '2021-12-09', '2021-12-10', '2021-12-11', '2021-12-12',
			 '2021-12-13'], dtype='datetime64[ns]', freq='D')
'''




1-3. DataFrame의 열 이름 추출 :    .columns
df.columns

df.columns

#결과
'''
Index(['A', 'B', 'C', 'D'], dtype='object')
'''

 

 

1-4. DataFrame의 데이터 추출 :    .values

df.values

#결과
'''
array([[-1.20813136, -2.19450481, -0.59223586,  0.08083421],
       [-1.19540232, -0.32713473, -1.63043123,  1.32610628],
       [ 0.11188354,  3.09661086, -0.28274477,  0.51399573],
       [ 1.03299367, -1.05155713,  1.02030745,  1.17211909],
       [ 0.22364942,  0.16708882, -0.99196838,  1.08059654],
       [ 0.992869  , -1.63620388,  0.35790354, -1.77796449]])
'''

 

 


1-5. DataFrame의 전체 정보 추출 :    .info()

    데이터 안에 null값이 있는지 확인 가능

df.info()

#결과
'''
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 6 entries, 2021-12-08 to 2021-12-13
Freq: D
Data columns (total 4 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   A       6 non-null      float64
 1   B       6 non-null      float64
 2   C       6 non-null      float64
 3   D       6 non-null      float64
dtypes: float64(4)
memory usage: 240.0 bytes
'''

 



1-5. DataFrame의 통계 요약 :    .describe()

df.describe()

#결과
'''
              A         B         C         D
count  6.000000  6.000000  6.000000  6.000000
mean  -0.007023 -0.324283 -0.353195  0.399281
std    1.000367  1.881051  0.948012  1.164083
min   -1.208131 -2.194505 -1.630431 -1.777964
25%   -0.868581 -1.490042 -0.892035  0.189125
50%    0.167766 -0.689346 -0.437490  0.797296
75%    0.800564  0.043533  0.197741  1.149238
max    1.032994  3.096611  1.020307  1.326106
'''




2.  데이터 정렬 함수

 

2-1. DataFrame의 특정 열 기준으로 데이터 정렬 :    .sort_values(by=기준 열, ascending=True/False)

df.sort_values(by='B', ascending=False)
df.sort_values(by='B', ascending=True)

#결과
'''
                   A         B         C         D
2021-12-10  0.111884  3.096611 -0.282745  0.513996
2021-12-12  0.223649  0.167089 -0.991968  1.080597
2021-12-09 -1.195402 -0.327135 -1.630431  1.326106
2021-12-11  1.032994 -1.051557  1.020307  1.172119
2021-12-13  0.992869 -1.636204  0.357904 -1.777964
2021-12-08 -1.208131 -2.194505 -0.592236  0.080834

                   A         B         C         D
2021-12-08 -1.208131 -2.194505 -0.592236  0.080834
2021-12-13  0.992869 -1.636204  0.357904 -1.777964
2021-12-11  1.032994 -1.051557  1.020307  1.172119
2021-12-09 -1.195402 -0.327135 -1.630431  1.326106
2021-12-12  0.223649  0.167089 -0.991968  1.080597
2021-12-10  0.111884  3.096611 -0.282745  0.513996
'''

 

 

 

2-2. DataFrame의 index 기준으로 데이터 정렬 :    .sort_index(ascending=True/False)

df.sort_index(ascending=False)

#결과
'''
                   A         B         C         D
2021-12-13  0.992869 -1.636204  0.357904 -1.777964
2021-12-12  0.223649  0.167089 -0.991968  1.080597
2021-12-11  1.032994 -1.051557  1.020307  1.172119
2021-12-10  0.111884  3.096611 -0.282745  0.513996
2021-12-09 -1.195402 -0.327135 -1.630431  1.326106
2021-12-08 -1.208131 -2.194505 -0.592236  0.080834
'''

 

 

 

3.  데이터 추출 함수

 

3-1. DataFrame의 index와 열 이름으로 데이터 추출

#DataFrame의 열 이름으로 데이터 추출 : DataFrame[열 이름]
df['A']

#결과
'''
2021-12-08   -1.208131
2021-12-09   -1.195402
2021-12-10    0.111884
2021-12-11    1.032994
2021-12-12    0.223649
2021-12-13    0.992869
Freq: D, Name: A, dtype: float64
'''



#DataFrame의 내부 index로 데이터 추출 : DataFrame[시작index : 끝index]
df[0 : 3]

#결과
'''
                   A         B         C         D
2021-12-08 -1.208131 -2.194505 -0.592236  0.080834
2021-12-09 -1.195402 -0.327135 -1.630431  1.326106
2021-12-10  0.111884  3.096611 -0.282745  0.513996
'''



#DataFrame의 index 이름으로 데이터 추출 : DataFrame[시작index이름 : 끝index이름]
df['2021-12-08' : '2021-12-13']

#결과
'''
                   A         B         C         D
2021-12-08 -1.208131 -2.194505 -0.592236  0.080834
2021-12-09 -1.195402 -0.327135 -1.630431  1.326106
2021-12-10  0.111884  3.096611 -0.282745  0.513996
2021-12-11  1.032994 -1.051557  1.020307  1.172119
2021-12-12  0.223649  0.167089 -0.991968  1.080597
2021-12-13  0.992869 -1.636204  0.357904 -1.777964
'''



#DataFrame의 열 이름과 index 이름으로 데이터 추출 : DataFrame.loc[시작index이름 : 끝index이름, [열 이름, 열 이름]]
df.loc['2021-12-08' : '2021-12-10', ['A', 'B']]

#결과
'''
                   A         B
2021-12-08 -1.208131 -2.194505
2021-12-09 -1.195402 -0.327135
2021-12-10  0.111884  3.096611
'''

 

 

 

3-2. 비교 연산자를 사용해 데이터 추출 :    DataFrame[DataFrame.열이름 비교연산 비교값]

#A열의 값이 0보다 큰 모든 열과 행의 값
df[df.A > 0]

#결과
'''
                   A         B         C         D
2021-12-10  0.111884  3.096611 -0.282745  0.513996
2021-12-11  1.032994 -1.051557  1.020307  1.172119
2021-12-12  0.223649  0.167089 -0.991968  1.080597
2021-12-13  0.992869 -1.636204  0.357904 -1.777964
'''

 

 

 

3-3. DataFrame 복사 :    복사된DataFrame이름  = 기존DataFrame이름.copy()

df2 = df.copy()

 

 

 


3-4. DataFrame에 새로운 열과 데이터 추가 :   
DataFrame[새 열 이름]  =  [신규 데이터]

df2['E'] = ['one', 'two', 'three', 'four', 'one', 'two']

#결과
'''
                   A         B         C         D      E
2021-12-08 -1.208131 -2.194505 -0.592236  0.080834    one
2021-12-09 -1.195402 -0.327135 -1.630431  1.326106    two
2021-12-10  0.111884  3.096611 -0.282745  0.513996  three
2021-12-11  1.032994 -1.051557  1.020307  1.172119   four
2021-12-12  0.223649  0.167089 -0.991968  1.080597    one
2021-12-13  0.992869 -1.636204  0.357904 -1.777964    two
'''

 

 


3-5. DataFrame의 특정 열에 지정 데이터가 포함 여부 True / False로 산출 :

    DataFrame[DataFrame['특정 열']].isin(['조회 값1', '조회 값2' ... '조회 값n'])

df2['E'].isin(['two', 'three'])

#결과
'''
2021-12-08    False
2021-12-09     True
2021-12-10     True
2021-12-11    False
2021-12-12    False
2021-12-13     True
Freq: D, Name: E, dtype: bool
'''

 

 

4.  DataFrame 연결

 

4-1. 여러 DataFrame을 차례로 연결해 새로운  DataFrame 생성 :    .concat()

    새DataFrame이름 = Pandas.concat([DataFrame1, DataFrame2 ... DataFrameN])

df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'], 
                    'B': ['B0', 'B1', 'B2', 'B3'],
                    'C': ['C0', 'C1', 'C2', 'C3'],
                    'D': ['D0', 'D1', 'D2', 'D3']}, index=[0, 1, 2, 3])
df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],
                    'B': ['B4', 'B5', 'B6', 'B7'],
                    'C': ['C4', 'C5', 'C6', 'C7'],
                    'D': ['D4', 'D5', 'D6', 'D7']}, index=[4, 5, 6, 7])
df3 = pd.DataFrame({'A': ['A8', 'A9', 'A10', 'A11'],
                    'B': ['B8', 'B9', 'B10', 'B11'],
                    'C': ['C8', 'C9', 'C10', 'C11'],
                    'D': ['D8', 'D9', 'D10', 'D11']}, index=[8, 9, 10, 11])
result = pd.concat([df1, df2, df3])

#결과
'''
      A    B    C    D
0    A0   B0   C0   D0
1    A1   B1   C1   D1
2    A2   B2   C2   D2
3    A3   B3   C3   D3
4    A4   B4   C4   D4
5    A5   B5   C5   D5
6    A6   B6   C6   D6
7    A7   B7   C7   D7
8    A8   B8   C8   D8
9    A9   B9   C9   D9
10  A10  B10  C10  D10
11  A11  B11  C11  D11
'''

 

 


4-2. DataFrame 연결 시 레벨에 해당하는 key 부여 :    keys = [list]

dfs = pd.concat([df1, df2, df3], keys=['x', 'y', 'z'])

#결과
'''
        A    B    C    D
x 0    A0   B0   C0   D0
x 1    A1   B1   C1   D1
x 2    A2   B2   C2   D2
x 3    A3   B3   C3   D3
y 4    A4   B4   C4   D4
y 5    A5   B5   C5   D5
y 6    A6   B6   C6   D6
y 7    A7   B7   C7   D7
z 8    A8   B8   C8   D8
z 9    A9   B9   C9   D9
z 10  A10  B10  C10  D10
z 11  A11  B11  C11  D11
'''

 

 

 

4-3. 행으로 데이터 연결 :    열 이름 기준

df4 = pd.DataFrame({'B': ['B2', 'B3', 'B6', 'B7'],
                    'D': ['C2', 'C3', 'C6', 'C7'],
                    'F': ['D2', 'D3', 'D6', 'D7']}, index=[2, 3, 6, 7])
df14 = pd.concat([df1, df4])

#결과
'''
     A   B    C   D    F
0   A0  B0   C0  D0  NaN
1   A1  B1   C1  D1  NaN
2   A2  B2   C2  D2  NaN
3   A3  B3   C3  D3  NaN
2  NaN  B2  NaN  C2   D2
3  NaN  B3  NaN  C3   D3
6  NaN  B6  NaN  C6   D6
7  NaN  B7  NaN  C7   D7
'''

key 값이 동일한 열에 차례로 연결, 기본값이 axis=0으로 생략 가능.




4-4. 열로 데이터 연결 :    index 기준

df14s = pd.concat([df1, df4], axis=1)

#결과
'''
     A    B    C    D    B    D    F
0   A0   B0   C0   D0  NaN  NaN  NaN
1   A1   B1   C1   D1  NaN  NaN  NaN
2   A2   B2   C2   D2   B2   C2   D2
3   A3   B3   C3   D3   B3   C3   D3
6  NaN  NaN  NaN  NaN   B6   C6   D6
7  NaN  NaN  NaN  NaN   B7   C7   D7
'''

idex 이름이 동일한 행에 차례로연결, axis=1.




4-5. 행으로 데이터 연결 :    공통 열 기준

df14s0 = pd.concat([df1, df4], join='inner')

#결과
'''
    B   D
0  B0  D0
1  B1  D1
2  B2  D2
3  B3  D3
2  B2  C2
3  B3  C3
6  B6  C6
7  B7  C7
'''




4-6. 열로 데이터 연결 :    공통 행 기준

df14s1 = pd.concat([df1, df4], axis=1, join='inner')

#결과
'''
    A   B   C   D   B   D   F
2  A2  B2  C2  D2  B2  C2  D2
3  A3  B3  C3  D3  B3  C3  D3
'''




4-7. 새로운 index 부여해 연결 :    ignore_index=True

df140i = pd.concat([df1, df4])

#결과
'''
     A   B    C   D    F
0   A0  B0   C0  D0  NaN
1   A1  B1   C1  D1  NaN
2   A2  B2   C2  D2  NaN
3   A3  B3   C3  D3  NaN
2  NaN  B2  NaN  C2   D2
3  NaN  B3  NaN  C3   D3
6  NaN  B6  NaN  C6   D6
7  NaN  B7  NaN  C7   D7
'''



df140i = pd.concat([df1, df4], ignore_index=True)

#결과
'''
     A   B    C   D    F
0   A0  B0   C0  D0  NaN
1   A1  B1   C1  D1  NaN
2   A2  B2   C2  D2  NaN
3   A3  B3   C3  D3  NaN
4  NaN  B2  NaN  C2   D2
5  NaN  B3  NaN  C3   D3
6  NaN  B6  NaN  C6   D6
7  NaN  B7  NaN  C7   D7
'''

 

 

 

5.  DataFrame 병합

 

5-1. 여러 DataFrame을 병합해 새로운  DataFrame 생성

    Pandas.merge(DataFrame1, DataFrame2, on='key이름', how='병합방식')

a = pd.DataFrame({'key': ['K0', 'K4', 'K2', 'K3'],
                    'A': ['A0', 'A1', 'A2', 'A3'],
                    'B': ['B0', 'B1', 'B2', 'B3']})
b = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
                    'C': ['C0', 'C1', 'C2', 'C3'],
                    'D': ['D0', 'D1', 'D2', 'D3']})
pd.merge(a, b, on='key')

#결과
'''
  key   A   B
0  K0  A0  B0
1  K4  A1  B1
2  K2  A2  B2
3  K3  A3  B3

  key   C   D
0  K0  C0  D0
1  K1  C1  D1
2  K2  C2  D2
3  K3  C3  D3

  key   A   B   C   D
0  K0  A0  B0  C0  D0
1  K2  A2  B2  C2  D2
2  K3  A3  B3  C3  D3
'''

on으로 지정된 열의 값이 병합하려는 DataFrame의 동일 열의 값과 일치하는 행 기준으로만 병합.

how의 기본 값은 inner로 생략 가능.




5-2. how='left' : 왼쪽 DataFrame 기준, 해당 열에 

a = pd.DataFrame({'key': ['K0', 'K4', 'K2', 'K3'],
                    'A': ['A0', 'A1', 'A2', 'A3'],
                    'B': ['B0', 'B1', 'B2', 'B3']})
b = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
                    'C': ['C0', 'C1', 'C2', 'C3'],
                    'D': ['D0', 'D1', 'D2', 'D3']})
pd.merge(a, b, on='key', how='left')

#결과
'''
  key   A   B
0  K0  A0  B0
1  K4  A1  B1
2  K2  A2  B2
3  K3  A3  B3

  key   C   D
0  K0  C0  D0
1  K1  C1  D1
2  K2  C2  D2
3  K3  C3  D3

  key   A   B    C    D
0  K0  A0  B0   C0   D0
1  K4  A1  B1  NaN  NaN
2  K2  A2  B2   C2   D2
3  K3  A3  B3   C3   D3
'''

left에 있는 전체 열의 모든 값을 놓고 on으로 지정된 열의 값 기준으로 병합.

일치하면 값을 입력, 일치하지 않으면 NaN으로 대체.

 

 


5-3. how='right' : 오른쪽 DataFrame 기준, 

pd.merge(a, b, on='key', how='right')

#결과
'''
  key   A   B
0  K0  A0  B0
1  K4  A1  B1
2  K2  A2  B2
3  K3  A3  B3

  key   C   D
0  K0  C0  D0
1  K1  C1  D1
2  K2  C2  D2
3  K3  C3  D3

  key    A    B   C   D
0  K0   A0   B0  C0  D0
1  K1  NaN  NaN  C1  D1
2  K2   A2   B2  C2  D2
3  K3   A3   B3  C3  D3
'''

right에 있는 전체 열의 모든 값을 놓고 on으로 지정된 열의 값 기준으로 병합.

일치하면 값을 입력, 일치하지 않으면 NaN으로 대체.



 

6.  외부 파일을 DataFrame으로 읽어 오기

 

6-1. pandas.read_csv('파일경로')  /  pandas.read_excel('파일경로')

DataFrame = pd.read_csv('./data/csv/weather.csv', encoding='euc-kr')

#결과
'''
              일시  평균기온(°C)  최대 풍속(m/s)  평균 풍속(m/s)
0     2010-08-01      28.7         8.3         3.4
1     2010-08-02      25.2         8.7         3.8
2     2010-08-03      22.1         6.3         2.9
3     2010-08-04      25.3         6.6         4.2
4     2010-08-05      27.2         9.1         5.6
         ...       ...         ...         ...
3648  2020-07-27      22.1         4.2         1.7
3649  2020-07-28      21.9         4.5         1.6
3650  2020-07-29      21.6         3.2         1.0
3651  2020-07-30      22.9         9.7         2.4
3652  2020-07-31      25.7         4.8         2.5

[3653 rows x 4 columns]
'''

 

 


6-2. 특정 열을 index로 지정해 파일 읽어 오기 :    index_col=index로 지정할 열의 순서(번호)

df_my_index = pd.read_csv('./data/csv/countries.csv', encoding='euc-kr', index_col=0)

Pandas의 .read_csv()함수는 파일의 첫번째 행을 각 Series의 열 이름으로 자동 설정 후,

각 행에 대한 index는 0으로 시작하는 정수의 나열로 자동 생성.

index_col=을 사용하면 특정 열을 자체를 index로 사용할 수 있음.

 

 

 

6-3. 한글 및 영문 encoding 오류 해결 :    encoding='cp949', 'utf-8', 'euc-kr' 

 

 

 

6-4. 특정 데이터 선택

#열 이름 이용 : DataFrame['열 이름']
df_my_index['country']

#결과
'''
KR     Korea
US       USA
JP     Japan
CN     China
RU    Russia
Name: country, dtype: object
'''


                
#각 열의 이름을 list로 설정해 다중 열 선택 : DataFrame[['열 이름', '열 이름' ...]]
df_my_index[['country', 'capital']]

#결과
'''
   country     capital
KR   Korea       Seoul
US     USA  Washington
JP   Japan       Tokyo
CN   China     Beijing
RU  Russia      Moscow
'''



#슬라이싱을 이용한 행 선택 : DataFrame[ : ]
df_my_index[:3]

#결과
'''
   country     area     capital  population
KR   Korea    98480       Seoul    51780579
US     USA  9629091  Washington   331002825
JP   Japan   377835       Tokyo   125960000
'''



#특정 record 한개만 선택 : DataFrame.loc['행', '열']
df_my_index.loc['US', 'capital']

#결과
'''
'Washington'
'''



#특정 열의 특정 행 선택 : DataFrame['열'][행index번호]
df_my_index['capital'][1]

#결과
'''
'Washington'
'''



#특정 열의 다중 행 선택 : DataFrame['열'][행index번호슬라이싱]
df_my_index['capital'][:3]

#결과
'''
KR         Seoul
US    Washington
JP         Tokyo
Name: capital, dtype: object
'''

 

 

 

6-5. 각 열을 연산 처리 후, 새로운 열로 생성 :    DataFrame['새로운 열 이름'] = 새로운 데이터

#df_my_index에 인구밀도를 나타내는 'density' 열 추가 : 인구밀도 = 인구/면적
df_my_index['density'] = df_my_index['population']/df_my_index['area']

#결과
'''
KR    525.797918
US     34.375293
JP    333.373033
CN    149.977044
RU      8.581789
Name: density, dtype: float64
'''

df_my_index['population']/df_my_index['area']와 같이 DataFrame의 어떤 열이 다른 열의 값에 의해 결정될 때,
행 별로 반복하여 연산하는 것이 아니라 필요한 열에 통째로 접근하여 한꺼번에 처리.

 

 

 

6-6. 표준편차 산출 :    .std()

#pandas 이용
import numpy as np
pandas_std = df_my_index['평균기온'].std()

#결과
'''
579579005.3714743
'''



#numpy 이용
import numpy as np
numpy_std = np.std(df_my_index['평균기온'])

#결과
'''
518391221.7369328
'''

pandas와 numpy는 계산 방식이 달라, 동일한 데이터의 산출 값이 차이 남.

+ Recent posts