본문 바로가기

Data_Analysis_Track_33/Python_문제풀이

Python_10_문제풀이(matplotlab, seaborn)

 

 

필요한 라이브러리 모두 불러오기

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import datetime
import warnings
warnings.filterwarnings(action = 'ignore')

 

pd.read_csv -> csv 파일을 읽어오기

encoding = 'cp949' -> default값인 UTF-8에서 에러가 뜰 시에 입력(오래된 자료일 경우 이런 오류가 발생)

# 상반기, 하반기 주유소 가격 데이터 조회
df1 = pd.read_csv('data/2022년_서울_상반기_일별_가격.csv', encoding = 'cp949')
df2 = pd.read_csv('data/2022년_서울_하반기_일별_가격.csv', encoding = 'cp949')

 

DataFrame 합치기

pd.concat([df, df]) -> 두 개의 DataFrame을 합친다.

# 상반기, 하반기 DataFrame 합치기
df_concat = pd.concat([df1, df2], ignore_index = True) # 원본의 index이름을 무시하고 붙인다.
df_concat

 

# DataFrame 기본 정보 조회
df_concat.info()

 

수치형과 문자형 각각의 통계량 확인 -> df.describe()

# 통계량
df_concat.describe() # 수치형
df_concat.describe(include = 'object') # 문자형

 

df['column'].unique() ->  특정 column의 고유값 조회

# 상표 컬럼의 고유값 조회
df_concat['상표'].unique()

# 지역 컬럼의 고유값 조회
df_concat['지역'].unique()

df['column'].str.removeprefix('str') -> df의 특정 컬럼의 str문자열을 제외한 컬럼 생성

# 지역 컬럼의 값을 이용하여 "구" 컬럼 생성 (지역에서 구만 추출해서 파생변수컬럼 생성)
df_concat['구'] = df_concat['지역'].str.removeprefix('서울 ')
# 강사님 버전
df_concat['구'] = df_concat['지역'].apply(lambda addr : addr.split()[1])

df_concat

 

pd.to_datetime(df['column'], format = '~~') -> 특정 column을 datetime 타입으로 변경

# 기간 컬럼을 datetime 타입으로 변경
df_concat['기간'] = pd.to_datetime(df_concat['기간'], format = '%Y%m%d')
df_concat['기간']

 

df['column'].dt.month -> 특정 datetime 타입의 column의 특정 속성만 빼서 생성(month, day, weekday 등..)

# 기간 컬럼을 이용해 "월", "일", "요일" 컬럼 생성 (dt accessor 이용)
df_concat['월'] = df_concat['기간'].dt.month
df_concat['일'] = df_concat['기간'].dt.day
df_concat['요일'] = df_concat['기간'].dt.weekday

 

df['column'].replace([n1, ~~], [n2, ~~]) -> 특정 column의 n1 ~ 값들을 n2 ~값들로 변경

inplace = True -> 원본을 함께 변경 (default = False)

# 요일 - 0:월, 1:화, 2:수, 3:목, 4:금, 5:토, 6:일 로 변경
df_concat['요일'].replace([0, 1, 2, 3, 4, 5, 6], ['월', '화', '수', '목', '금', '토', '일'], inplace = True) 
df_concat['요일']

# 강사님 버전
df_concat['요일'] = df_concat['요일'].apply(lambda x : '월화수목금토일'[x]) # +'요일')
df_concat['요일']

 

df.to_csv('경로') -> DataFrame을 경로 장소에 csv파일로 저장

# 전처리한 DataFrame -> 저장
df_concat.to_csv('data/2022년_서울주유소_데이터셋.csv', index = False)

 

df.sort_values('column') -> 특정 컬럼의 값들을 정렬

ascending = False -> 내림차순으로 정렬 (default -> True(오름차순))

# 휘발유 가격이 가장 비싼 5개 행 조회
df_concat.sort_values('휘발유', ascending = False).head(5)

 

DataFrame의 columns별 null값 개수 조회

df_concat.isnull().sum()

 

np.NaN -> null값을 의미

# 휘발유 가격이 가장 저렴한 5개 행 조회 (단 0원인 주유소 제외)
# df_concat = df_concat.replace(0, np.NaN) # 0을 NaN값 처리
df_concat.sort_values(['휘발유']).head(5)

# 강사님 풀이
df_concat.query('휘발유 != 0').sort_values('휘발유').head(5)

 

df.groupby('column1')['column2'] -> column1에 대한 column2의 값들 조회

df.['column'].mean() -> DataFrame의 column의 값들의 평균

# 상표별 휘발유 평균가격 조회
df_concat.groupby('상표')['휘발유'].mean()

# 강사님 풀이
# 0원인 주유소는 빼고 계산
휘발유_상표별_평균 = df_concat.query('휘발유 != 0').groupby('상표')['휘발유'].mean()
휘발유_상표별_평균

 

df.plot(kind = 'type', ~) -> DataFrame의 값 type의 형태로 시각화

plt.axhline(data) -> data에 대한 값의 수평선 그리기

# 상표별 휘발유 평균가격 시각화
전체평균 = df_concat['휘발유'].mean()

# 상표별 평균 시각화
휘발유_상표별_평균.sort_values(ascending = False).plot(kind = 'bar', rot = 45)

# 전체평균 표시
plt.axhline(전체평균, color = 'red', linestyle = ':', label = f"전체평균 : {전체평균}")
plt.legend(bbox_to_anchor = (1,1), loc = 'upper left')
plt.show()

 

normalize = True -> 값들의 비율 조회

 

# 셀프주유소와 일반주유소 개수 확인
df_concat.value_counts(['셀프여부'])
df_concat.value_counts(['셀프여부'], normalize = True) # 비율
# df_concat['셀프여부'].value_counts

 

unstack() -> index 값을 column으로 올려준다.

# 상표별 일반/셀프 주유소의 휘발유 가격 평균 비교
df_concat.query('휘발유 != 0').groupby(['상표', '셀프여부'])['휘발유'].mean()
df_concat.query('휘발유 != 0').groupby(['상표', '셀프여부'])['휘발유'].mean().unstack()

 

df.pivot_table() -> 피봇테이블(pivot table)이란 데이터 열 중에서 두 개의 열을 각각 행 인덱스, 열 인덱스로 사용하여 데이터를 조회하여 펼쳐놓은 것을 말한다.

margins = True -> 각 행과 열의 값들의 합산을 조회

# pivot table
상표_셀프여부_휘발유_평균 = df_concat.query('휘발유 != 0').pivot_table(index = '상표', columns = '셀프여부', values = '휘발유', aggfunc = 'mean', margins = True)
상표_셀프여부_휘발유_평균

 

  • DataFrame.plot()
  • index명이 x축으로 들어오고 컬럼의 값을 이용해서 그래프를 그림.
  • 컬럼이 여러개일때는 하나의 Axes에 따로 따로 그린다.

 

# 상표별 일반/셀프 주유소의 휘발유 가격 평균 비교 시각화
# 상표_셀프여부_휘발유_평균에서 All을 빼고 시각화
상표_셀프여부_휘발유_평균.iloc[:-1,:-1].plot(kind = 'bar', rot = 45)
plt.legend(bbox_to_anchor = (1,1), loc = 'upper left')
plt.show()

 

sns.boxplot(data = 'df', y = 'column1', x = 'column2') -> df의 data들을 column1과 2로 시각화 

boxplot은 극단치 측정에 활용

# 상표별 휘발유 가격의 분포를 boxplot으로 시각화
# 범주형 컬럼을 이용해 group별로 나눠서 시각화 ---> seaborn 사용이 편하다.
plt.figure(figsize = (10, 6))
sns.boxplot(data = df_concat.query('휘발유 != 0')
            ,y = '휘발유'
            ,x = '상표'
           )
plt.show()

 

sns.violinplot (data = 'df', y = 'column1', x = 'column2')

plt.figure(figsize = (10, 6))
sns.violinplot(data = df_concat.query('휘발유 != 0')
            ,y = '휘발유'
            ,x = '상표'
           )
plt.show()

 

hue = 'columns' -> 분류 기준을 하나 더 추가

# 상표별 일반/셀프 주유소의 휘발유 가격에 대한 분포 확인 - boxplot으로 시각화
plt.figure(figsize = (10, 6))
sns.boxplot(data = df_concat.query('휘발유 != 0')
            ,y = '휘발유'
            ,x = '상표'
            ,hue = '셀프여부'
           )
plt.show()

 

violinplot에 hue추가

plt.figure(figsize = (10, 6))
sns.violinplot(data = df_concat.query('휘발유 != 0')
            ,y = '휘발유'
            ,x = '상표'
            ,hue = '셀프여부'
           )
plt.show()

# 구별 휘발유 가격의 평균
구별_휘발유_평균 = df_concat.query('휘발유 != 0').groupby('구')['휘발유'].mean().sort_values(ascending = False)
구별_휘발유_평균

 

df.idxmax() -> 가장 높은 value의 index명 가져오기

# 평균 가격이 가장 높은 구의 상표별 휘발유 평균가격
h_price = df_concat.query('휘발유 != 0').groupby('구')['휘발유'].mean().idxmax()
df_concat[df_concat['구'] == h_price].groupby('상표')['휘발유'].mean()

# 다른 방법
구별_휘발유_평균.index[0]
df_concat.query('구 == @구별_휘발유_평균.index[0]').groupby('상표')['휘발유'].mean()

 

# 월 평균 휘발유 가격
월별_휘발유_평균 = df_concat.query('휘발유 != 0').groupby('월')['휘발유'].mean()
월별_휘발유_평균

 

# 각 구의 월별 평균 휘발유 가격 
월_구별_휘발유_평균가격 = df_concat.query('휘발유 != 0').groupby(['구', '월'])['휘발유'].mean()
월_구별_휘발유_평균가격.unstack()

 

# pivot_table 사용
월_구별_휘발유_평균가격 = round(df_concat.query('휘발유 != 0').pivot_table(index= '월', columns = '구', values = '휘발유', aggfunc = 'mean'), 2)
월_구별_휘발유_평균가격

 

# 한개 구(강남구)
월_구별_휘발유_평균가격['강남구'].plot(figsize = (10, 4), marker = '.')

 

# 각 구의 월별 평균가격의 변화추이 시각화
월_구별_휘발유_평균가격.plot(figsize = (15, 5))
plt.legend(bbox_to_anchor = (1, 1), loc = 'upper left', ncol = 3, title = '구')
plt.show()

 

# 가장 휘발유가격이 비싼 주유소 상위 5 - (같은 주유소가 여러개 나오므로 가장 비싼 가격을 기준으로 집계)
# 주유소별로 제일 비쌀때 가격.
휘발유_비싼_주유소 = df_concat.query('휘발유 != 0').groupby(['상호', '주소'])['휘발유'].max().sort_values(ascending = False).head(5)
휘발유_비싼_주유소

# 가장 휘발유가격이 저렴한 주유소 상위 5 - (같은 주유소가 여러개 나오므로 가장 비싼 가격을 기준으로 집계)
휘발유_싼_주유소 = df_concat.query('휘발유 != 0').groupby(['상호', '주소'])['휘발유'].max().sort_values().head(5)
휘발유_싼_주유소

 

multi index, level

df.index.get_level_values(level)

# 휘발유_비싼_주유소.head().index
# multi index에서 index명을 각각 조회
휘발유_비싼_주유소.head().index.get_level_values(0) # level 지정하면 그 level의 index이름들을 묶어서 반환
# 휘발유_비싼_주유소.head().index.get_level_values(1)

 

# 휘발유 비싼 주유소의 상위 5개의 상호, 주소, 상표, 셀프여부,  조회 - 위에서 조회한 결과에 추가 정보(상표, 셀프여부 등) 조회 (중복제거-drop_duplicates)
df_concat.query('상호 in @휘발유_비싼_주유소.head().index.get_level_values(0) and 주소 in @휘발유_비싼_주유소.head().index.get_level_values(1)')[['상호','주소','상표','셀프여부']].drop_duplicates()

# 휘발유 저렴한 주유소의 상위 5개의 상호, 주소, 상표, 셀프여부,  조회 - 위에서 조회한 결과에 추가 정보(상표, 셀프여부 등) 조회 (중복제거-drop_duplicates)
df_concat.query('상호 in @휘발유_싼_주유소.head().index.get_level_values(0) and 주소 in @휘발유_싼_주유소.head().index.get_level_values(1)')[['상호','주소','상표','셀프여부']].drop_duplicates()

 

size()

# 고급 휘발유를 가장 많이 파는 구 조회
df_concat.query('고급휘발유 != 0').groupby('구')['고급휘발유'].size().idxmax()

 

drop_duplicates()

# 고급 휘발유를 가장 많이 파는 구 조회 -> 실제 주유소가 몇개인지.
df_concat.query('고급휘발유 != 0')[['구', '상호', '주소']].drop_duplicates().groupby('구')['상호'].count().sort_values(ascending = False)