Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

여유로움

[11.23 화] 빅데이터 분석기사 실기 - Pandas (21~23강) 본문

셀프스터디/빅데이터 분석기사

[11.23 화] 빅데이터 분석기사 실기 - Pandas (21~23강)

티로즈 2021. 11. 23. 22:38

1. 결측치 확인

# [3-23] df의 행별 결측치를 조사합니다.
df.isna().sum(axis=0)
# [3-24] '측정일시'를 index로 설정하고, 
# index 기준으로 오름차순 정렬해서 df1으로 이름 붙입니다.
# 그래프에서 y축으로 사용하려고 합니다.
df1 = df.set_index('측정일시').sort_index()
df1.head()
df['컬럼명'] : 1개의 컬럼을 Series로 반환
df[['컬럼명1''컬럼명2', ...]]  : 여러개의 컬럼을 DataFrame으로 반환
df['행이름1':'행이름N'] : 행이름1 ~ 행이름 N 전까지를 반환
df[조건] : 행 중에서 조건이 True인 행을 반환
# [3-26] df1에서 '측정소명', '년', '월', '일','오존농도(ppm)', '미세먼지(㎍/㎥)', '초미세먼지(㎍/㎥)'컬럼만 
# 추출하여 df_dust 라는 이름을 정의합니다.
df_dust = df1[['측정소명''년''월''일','오존농도(ppm)''미세먼지(㎍/㎥)''초미세먼지(㎍/㎥)']]
# [3-27] df_dust의 컬럼별 결측치 개수를 구해봅니다
df_dust.isna().sum()

 

2. DataFrame의 index, columns 설정

  • DataFrame의 index를 columns로 사용 : DataFrame.reset_index()
  • DataFrame의 columns를 index로 사용 : DataFrame.set_index('컬럼이름')
# [3-29] df_dust의 index를 다시 컬럼으로 사용되도록 합니다.
# 다음 작업인 결측치 삭제를 사용하기 위함
df_dust = df_dust.reset_index()
df_dust.head(2)

 

3. 결측치 제거

DataFrame.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)
  • 결측치 제거에 사용되는 메서드
  • how='any' : 결측치가 하나라도 포함된 행 삭제
  • how='all' : 모든 데이터가 결측치인 행 삭제
  • axis=1 : 컬럼에 대해 동작
  • thresh=숫자 : 숫자 이상의 데이터를 가진 행은 삭제 안함
  • subset=[컬럼이름1, ...] : subset으로 지정된 컬럼만 사용하여 삭제 대상 검색
# [3-31] df_dust 에서 ['오존농도(ppm)','미세먼지(㎍/㎥)', '초미세먼지(㎍/㎥)']에서 
# 하나라도 결측치가 있는 행을 제거하여 결과를 temp2로 저장합니다.
temp2 = df_dust.dropna(how='any', subset=['오존농도(ppm)','미세먼지(㎍/㎥)''초미세먼지(㎍/㎥)'])

# df_dust와 temp2의 행의 수 (len)을 확인하여 제거된 행의 개수를 확인합니다.
print(len(df_dust)-len(temp2))

# [3-32] df_dust 에서 ['오존농도(ppm)','미세먼지(㎍/㎥)', '초미세먼지(㎍/㎥)']에서 
# 2개 이상의 데이터를 가진 행은 제거하지 않은 결과를 temp3로 저장합니다.
# (= 3개의 정보 중 1개의 데이터만 가진 행을 제거함)
temp3 = df_dust.dropna(thresh=2, subset=['오존농도(ppm)','미세먼지(㎍/㎥)''초미세먼지(㎍/㎥)'])


# df_dust와 temp3의 행의 수 (len)을 확인하여 제거된 행의 개수를 확인합니다.
print(len(df_dust)-len(temp3))

 

4. groupby 함수

df.groupby(by=[컬럼1, 컬럼2, ...]).함수()
  • 그룹 기준으로 목록을 지정하면 MultiIndex로 만들어짐
  • MultiIndex인 경우의 indexing은 tuple을 사용함
  • ['년', '월']을 그룹 기준으로 사용한 경우 (2017, 6) 처럼 지정함
# [3-34] df_dust에서 '년', '월'별 '미세먼지(㎍/㎥)' 데이터의 평균을 구해
# DataFrame으로 만들어 meandf 라는 이름을 지정합니다.ㅣ
meandf = df_dust.groupby(['년','월'])[['미세먼지(㎍/㎥)']].mean()
meandf
# [3-35] meandf에서 2017년 6월까지의 데이터만 출력합니다.
meandf.loc[:(2017,6),:]
# [3-36] meandf에 '결측치제거후' 및 '차이'라는 컬럼을 추가합니다.
# '결측치제거후' 컬럼은 temp2에서 '년', '월'별 '미세먼지(㎍/㎥)' 데이터의 평균을 사용합니다.
# '차이' 컬럼은 '미세먼지(㎍/㎥)' - '결측치제거후' 를 사용합니다.
meandf['결측치제거후']=temp2.groupby(['년','월'])['미세먼지(㎍/㎥)'].mean()
meandf['차이']=meandf['미세먼지(㎍/㎥)']-meandf['결측치제거후']
# [3-37] meandf에서 2017년 6월까지의 데이터만 출력합니다.
# 여러 개의 값에 차이가 있는 것을 확인 할 수 있습니다.
meandf.loc[:(2017,6),:]

 

5. 결측치 대체(평균값)

Series.mask(조건, 조건이 참일 때 사용할 값 또는 값 목록)
  • 조건이 True인 것에 대해 다른 값을 변경합니다.
  • s.isna() : NA값에 대해 True, NA아닌 것은 False
Series.where(조건, 조건이 거짓일 때 사용할 값 또는 값 목록)
  • 조건이 False인 것에 대해서 다른 값으로 변경합니다.
  • s.notna() : NA값에 대해 False, NA아닌 것은 True
# [3-38] where 연습을 위한 temp 생성
import numpy as np
temp = pd.DataFrame({'A':[np.nan, 2, np.nan, 4],
                     'B':[78910],
                     'C':[1248]})
temp
# temp의 'A' 열에 대해서 결측치인 경우 'B'의 값으로 대체합니다.
temp['A'].mask(temp['A'].isna(), temp['B'])
#temp['A].where(temp['A'].notna(), temp['B'])
# temp의 'A' 열에 대해서 결측치인 경우 'C'의 값으로 대체합니다.
temp['A'].mask(temp['A'].isna(),temp['C'])

 

df.groupby(그룹기준컬럼)[함수를 적용할 컬럼명].transform(함수)
  • index가 유지 되면서 그룹별 함수를 적용함
  • agg는 index가 그룹기준컬럼으로 변경됨
# [3-39] df_dust의 일자(년, 월, 일)별 '미세먼지(㎍/㎥)'의 평균을 구합니다.
# 이때, index 변경을 하지 않기 위해 transform을 사용하고, fine_dust라는 이름을 지정합니다.
fine_dust = df_dust.groupby(['측정일시'])['미세먼지(㎍/㎥)'].transform('mean')
fine_dust
# [3-40] df_dust['미세먼지(㎍/㎥)'], fine_dust의 결측치 값의 개수를 구합니다.
df_dust['미세먼지(㎍/㎥)'].isna().sum(), fine_dust.isna().sum()
# [3-41] df_dust의 '미세먼지(㎍/㎥)'의 결측치를 fine_dust의 값으로 채우기 합니다.
# 채우기 한 결과를 다시 df_dust['미세먼지(㎍/㎥)']로 저장합니다.
df_dust['미세먼지(㎍/㎥)'] = df_dust['미세먼지(㎍/㎥)'].mask(df_dust['미세먼지(㎍/㎥)'].isna(), fine_dust)

# [3-43] meandf에 '결측치대체' 및 '차이2'라는 컬럼을 추가합니다.
# '결측치대체' 컬럼은 df_dust에서 '년', '월'별 '미세먼지(㎍/㎥)' 데이터의 평균을 사용합니다.
# '차이2' 컬럼은 '미세먼지(㎍/㎥)' - '결측치대체'를 사용합니다.
meandf['결측치대체'] = df_dust.groupby(['년','월'])['미세먼지(㎍/㎥)'].mean()
meandf['차이2'] = meandf['미세먼지(㎍/㎥)'] - meandf['결측치대체']
# [3-44] meandf에서 2017년 6월까지의 데이터만 출력합니다.
# 차이가 없는 것을 확인합니다.
meandf.loc[:(2017,6),:]

# [3-45] df_dust의 '오존농도(ppm)', '초미세먼지(㎍/㎥)' 컬럼에 대해서도
# '미세먼지(㎍/㎥)'와 같이 동일한 '년', '월', '일'의 평균 값으로 채우기 합니다.
for i in ['오존농도(ppm)''초미세먼지(㎍/㎥)']:
  x = df_dust.groupby('측정일시')[i].transform('mean')
  s = df_dust[i]
  df_dust[i] = s.mask(s.isna(), x)

 

6. 객체로 저장

df_dust2 = pd.read_csv('fine_dust02.csv'#파일로 저장 후 가져오면 형변환 다시 해야함
df_dust2.isna().sum()
import shelve #객체로 저장했다가 가져오면 형변환 다시 할 필요 없음
with shelve.open('mydata'as data:
    data['fine_dust02'] = df_dust

import shelve
with shelve.open('mydata'as data:
    df_dust3 = data['fine_dust02']

 

7. 분석

# 데이터 값 실수. 소수점 넷째자리까지 표시
pd.options.display.float_format = '{:.2f}'.format
행, 열에 모두 group을 지정하여 통계값 구하기
  • DataFrame.pivot_table(index=행방향그룹열이름, columns=열방향그룹열이름, values=집계대상열이름, aggfunc=구할 통계값)
  • 각각에 대해 단독 또는 목록을 사용할 수 있음
  • index, columns는 범주형, values는 연속형 사용
  • values, aggfunc의 경우 단독의 경우 출력에 표시되지 않으나, 목록은 표시됨
# [3-48] df_dust의 월/년 별 미세먼지의 'mean', 'min', 'max' 구하기
# pivot_table 사용, values의 경우 목록으로 지정시와 단독 지정시가 다르게 표시됨
df_dust.pivot_table(index='월',columns='년',values='미세먼지(㎍/㎥)', aggfunc=['mean''min''max'])
# [3-49] df_dust에서 '측정소명'이 '강남구'인 데이터의
# 월별(index), 년별(columns), 미세먼지 농도 평균을 조회하여 temp로 저장합니다
place = df_dust.loc[df_dust['측정소명']=='강남구',:]
temp = place.pivot_table(index=['월'], columns=['년'], values=['미세먼지(㎍/㎥)'], aggfunc=['mean']) #평균은 기본값이므로 생략하면 평균값이 나옴
temp

 

8. Series

  • Series.argmax() : 가장 값이 큰 것의 integer index 구하기
  • Series.argmin() : 가장 값이 작은 것의 integer index 구하기
  • Series[Series.argmax()] : 가장 큰 값 구하기
  • Series[Series.argmin()] : 가장 작은 값 구하기
# argmin, argmax를 연습하기 위한 Series
s = pd.Series([10579268],
              index=list('ABCDEFGH'))
display(s['A'], s[['A''D']], s[s>5], s['C':'F']) 
# argmin(), argmax() 구하기
a = s.argmin()
b = s.argmax()
# [3-50] 2016년 ~ 2020년도 미세먼지 농도가 가장 높은 월의 위치
temp = df_dust.pivot_table(index=['년'],columns=['월'], values='미세먼지(㎍/㎥)', aggfunc='mean')

for year in temp.columns:
  idx = temp[year].argmax()
  print('{}년 미세먼지 농도 높은 월 : {}'.format(year, temp.index[idx]))

# [3-51] 2016년 ~ 2020년도 미세먼지 농도가 가장 낮은 월의 위치
for year in temp.columns:
  idx = temp[year].argmin()
  print('{}년 미세먼지 농도 높은 월 : {}'.format(year, temp.index[idx]))

# [3-52] 2016년 ~ 2019년 월별 미세먼지 평균을 구해 temp (DataFrame)로 저장합니다.
temp = df_dust.loc[df_dust['년']<=2019,:].groupby('월')[['미세먼지(㎍/㎥)']].mean()
# [3-53] 2020년 월별 미세먼지 평균을 구해 temp에 '미세먼지 2020' 컬럼으로 추가합니다.
temp['미세먼지 2020'] = df_dust.loc[df_dust['년']==2020,:].groupby('월')[['미세먼지(㎍/㎥)']].mean()
temp

출처 : 유튜브 강의 EduAtoZ