Learn & Record
Python (pandas, 날짜자동생성, DataFrame 데이터프레임, 연산, 파일읽기, 파일쓰기, 데이터확인, 데이터선택, 무료웹호스팅, 결측데이터, 데이터가공) 본문
Python (pandas, 날짜자동생성, DataFrame 데이터프레임, 연산, 파일읽기, 파일쓰기, 데이터확인, 데이터선택, 무료웹호스팅, 결측데이터, 데이터가공)
Walker_ 2024. 3. 12. 17:051. Pandas
- numpy의 경우 배열의 모든 원소가 데이터 타입이 같아야 했지만,
- pandas의 경우에는 원소의 데이터 타입이 달라도 저장 가능
import pandas as pd
import numpy as np
s2 = pd.Series(['a','b','c',5,6,7,8]) # 넘파이 였다면 모두를 문자열로 변경
print(s2)
# 데이터가 없으면 numpy를 임포트한 후에 np.nan으로 데이터가 없음을 표시할 수 있음
# 데이터를 위한 자리 index는 있지만 실제 값이 없음
s3 = pd.Series([np.nan, 10, 30])
print(s3)
# Series 데이터를 생성할 때 다음과 같이 인자로 index 추가 가능
# s = pd.Series(seq_data, index = index_seq)
# 인자로 index를 명시적으로 입력하면 Series 변수(s)의 index에는 자동생성되는 index 대신 index_seq가 들어가게 됨
# index_seq도 리스트와 튜플 타입의 데이터를 모두 사용가능하지만 주로 리스트를 사용
# 주의할 점은 seq_data의 항목 개수와 index_seq의 항목개수가 같아야 함
# 어느 가게의 날짜별 판매량을 pandas의 Series형식으로 입력. 하루는 데이터가 없어서 np.nan을 입력
index_data = ['2018-10-07', '2018-10-08', '2018-10-09', '2018-10-10']
s4 = pd.Series([200, 195, np.nan, 205], index=index_data)
print(s4)
# 2018-10-07 200.0
# 2018-10-08 195.0
# 2018-10-09 NaN
# 2018-10-10 205.0
# dtype: float64
print(s4.index)
# Index(['2018-10-07', '2018-10-08', '2018-10-09', '2018-10-10'], dtype='object')
# 파이썬의 딕셔너리를 사용하면 데이터와 index를 함께 입력할 수 있음
# s = pd.Series(dict_data)
# 입력 인자로 딕셔너리 데이터를 입력하면 딕셔너리 데이터의 키 key와 값 value이 각각
# Series 데이터의 index와 value로 들어감
s5 = pd.Series({'국어' : 100, '영어':95, '수학':90})
print(s5)
# 국어 100
# 영어 95
# 수학 90
# dtype: int64
2. 날짜 자동 생성 : date_range
- 입력해야 할 날짜가 많으면 pandas에서 날짜를 자동생성하는 date_range() 사용.
- 몇 가지 설정만 하면 원하는 날짜를 자동으로 생성하므로 날짜 데이터를 입력할 때 편리
# pd.date_range(start=None, end=None, periods=None, freq='0')
# start는 시작날짜
# end는 끝날짜
# periods는 날짜 데이터 생성 기간 -> 생성 갯수
# freq는 날짜 데이터 생성 주기
# start는 필수이고, end나 periods는 둘 중 하나만 있어도 됨
# freq는 입력하지 않으면 'D' 옵션이 설정돼 달력날짜 기준으로 하루씩 증가.
# * pandas date_range() 함수의 freq 옵션.
# 약어 설명 사용 예
# D : 달력 날짜 기준 하루 주기 ex) 하루 주기: freq = 'D', 이틀 주기: freq = '2D'
# B : 업무 날짜 기준 하루 주기 ex) 업무일(월~금) 기준으로 생성, freq = 'B', freq = '3B'
# W : 일요일 시작 기준 일주일 주기 ex) 월요일: W-MON, 화요일: W-TUE, freq = 'W', freq = 'W-MON'
# M : 월말 날짜 기준 주기 ex) 한 달 주기: freq = 'M', 네 달 주기: freq = '4M'
# BM : 업무 월말 날짜 기준 주기 ex) freq = 'BM' , freq = '2BM'
# MS : 월초 날짜 기준 주기 ex) freq = 'MS' , freq = '2MS'
# BMS : 업무 월초 날짜 기준 주기 ex) freq = 'BMS' , freq = '2BMS'
# Q : 분기 끝 날짜 기준 주기 ex) freq = 'Q' , freq = '2Q'
# BQ : 업무 분기 끝 날짜 기준 주기 ex) freq = 'BQ' , freq = '2BQ'
# QS : 분기 시작 날짜 기준 주기 ex) freq = 'QS' , freq = '2QS'
# BQS : 업무 분기 시작 날짜 기준 주기 ex) freq = 'BQS' , freq = '2BQS'
# A : 일년 끝 날짜 기준 주기 ex) freq = 'A' , freq = '2A'
# BA : 업무 일년 끝 날짜 기준 주기 ex) freq = 'BA' , freq = '2BA'
# AS : 일년 시작 날짜 기준 주기 ex) freq = 'AS' , freq = '2AS'
# BAS : 업무 일년 시작 날짜 기준 주기 ex) freq = 'BAS' , freq = '2BAS'
# H : 시간 기준 주기 ex) 1시간 주기: freq = 'H' , 2시간 주기: freq = '2H'
# BH : 업무 시간 기준 주기 ex) 업무 시간(09:00 ~ 17:00) 기준으로 생성
# T, min : 분 주기 ex) 10분 주기: freq = '10T' , 30분 주기: freq = '30min'
# S : 초 주기 ex) 1초 주기: freq = 'S' , 10초 주기: freq = '10S'
import pandas as pd
# 시작 날짜와 끝 날짜를 지정해 날짜 데이터를 생성. 하루씩 증가한 날짜 데이터가 생성
print(pd.date_range(start='2019-01-01', end='2019-01-07'))
# DatetimeIndex(['2019-01-01', '2019-01-02', '2019-01-03', '2019-01-04',
# '2019-01-05', '2019-01-06', '2019-01-07'],
# dtype='datetime64[ns]', freq='D')
# 날짜 데이터를 입력할 때 yyyy-mm-dd 형식이 아니라
# yyyy/mm/dd, yyyy.mm.dd, mm-dd-yyyy, mm/dd/yyyy, mm.dd.yyyy 같은 형식도 사용가능하고
# 대신 출력은 yyyy-mm-dd 형식으로 생성
print(pd.date_range(start='2019/01/01', end='2019.01.07'))
# DatetimeIndex(['2019-01-01', '2019-01-02', '2019-01-03', '2019-01-04',
# '2019-01-05', '2019-01-06', '2019-01-07'],
# dtype='datetime64[ns]', freq='D')
print(pd.date_range(start='01-01-2019', end='01/07/2019'))
# DatetimeIndex(['2019-01-01', '2019-01-02', '2019-01-03', '2019-01-04',
# '2019-01-05', '2019-01-06', '2019-01-07'],
# dtype='datetime64[ns]', freq='D')
print(pd.date_range(start='2019-01-01', end='01.07.2019'))
# DatetimeIndex(['2019-01-01', '2019-01-02', '2019-01-03', '2019-01-04',
# '2019-01-05', '2019-01-06', '2019-01-07'],
# dtype='datetime64[ns]', freq='D')
# 끝 날짜를 지정하지 않고 periods만 입력해서 날짜 생성
print(pd.date_range(start='2019-01-01', periods=7))
# DatetimeIndex(['2019-01-01', '2019-01-02', '2019-01-03', '2019-01-04',
# '2019-01-05', '2019-01-06', '2019-01-07'],
# dtype='datetime64[ns]', freq='D')
# 2일씩 증가하는 날짜를 생성
print(pd.date_range(start='2019-01-01', periods=4, freq='2D'))
# DatetimeIndex(['2019-01-01', '2019-01-03', '2019-01-05', '2019-01-07'], dtype='datetime64[ns]', freq='2D')
#달력의 요일을 기준으로 일주일씩 증가하는 날짜를 생성
print(pd.date_range(start='2019-01-01', periods=4, freq='W'))
# DatetimeIndex(['2019-01-06', '2019-01-13', '2019-01-20', '2019-01-27'], dtype='datetime64[ns]', freq='W-SUN')
# 업무일 기준 2개월 월말 주기로 12개 날짜를 생성
print(pd.date_range(start='2019-01-01', periods=12, freq='2BM'))
# DatetimeIndex(['2019-01-31', '2019-03-29', '2019-05-31', '2019-07-31',
# '2019-09-30', '2019-11-29', '2020-01-31', '2020-03-31',
# '2020-05-29', '2020-07-31', '2020-09-30', '2020-11-30'],
# dtype='datetime64[ns]', freq='2BM')
# 분기 시작일을 기준으로 4개의 날짜를 생성
print(pd.date_range(start='2019-01-01', periods=4, freq='QS'))
# DatetimeIndex(['2019-01-01', '2019-04-01', '2019-07-01', '2019-10-01'], dtype='datetime64[ns]', freq='QS-JAN')
- 날짜뿐 아니라 시간을 생성하는 방법
# 1시간 주기로 10개의 시간을 생성한 예
print(pd.date_range(start='2019-01-01 08:00', periods=10, freq='H'))
# DatetimeIndex(['2019-01-01 08:00:00', '2019-01-01 09:00:00',
# '2019-01-01 10:00:00', '2019-01-01 11:00:00',
# '2019-01-01 12:00:00', '2019-01-01 13:00:00',
# '2019-01-01 14:00:00', '2019-01-01 15:00:00',
# '2019-01-01 16:00:00', '2019-01-01 17:00:00'],
# dtype='datetime64[ns]', freq='H')
# 업무 시간을 기준으로 1시간 주기로 10개의 시간을 생성하는 예
# 업무 시간은 9시 부터 17시까지이므로 start시간을 9시 이전으로 설정해도 9시부터 표시
print(pd.date_range(start='2019-01-01 08:00', periods=10, freq='BH'))
# DatetimeIndex(['2019-01-01 09:00:00', '2019-01-01 10:00:00',
# '2019-01-01 11:00:00', '2019-01-01 12:00:00',
# '2019-01-01 13:00:00', '2019-01-01 14:00:00',
# '2019-01-01 15:00:00', '2019-01-01 16:00:00',
# '2019-01-02 09:00:00', '2019-01-02 10:00:00'],
# dtype='datetime64[ns]', freq='BH')
# date_range()를 이용해 Series의 index를 지정한 예.
index_date = pd.date_range(start='2019-03-01', periods=5, freq='D')
s = pd.Series([51, 62, 55, 49, 58], index=index_date)
print(s)
# 2019-03-01 51
# 2019-03-02 62
# 2019-03-03 55
# 2019-03-04 49
# 2019-03-05 58
# Freq: D, dtype: int64
3. 데이터프레임 DateFrame
- 표 Table와 2차원 데이터 처리를 위해 DataFrame을 제공
- 데이터 Data를 담는 틀 Frame 이라는 뜻
# DataFrame을 이용해 데이터를 생성하는 방법
# df = pd.DataFrame(data [, index = index_data, columns = columns_data])
# data 인자에는 리스트와 형태가 유사한 데이터 타입은 모두 사용 가능
# 즉 리스트, 딕셔너리, numpy의 배열 데이터, Series나 DataFrame 타입의 데이터 입력 가능
# 세로축 라벨ㅇ르 index라 하고, 가로축 라벨을 columns라고 함
# index와 columns를 제외한 부분을 values라고 하고 values가 관심있는 데이터
import pandas as pd
d1 = pd.DataFrame([[1,2,3], [4,5,6], [7,8,9]])
print(d1)
# 0 1 2
# 0 1 2 3
# 1 4 5 6
# 2 7 8 9
# values 부분에는 입력한 data가 순서대로 입력돼 있고
# 가장 좌측의 열과 가장 윗줄의 행에는 각각 숫자가 자동으로 생성되어 index, columns를 구성
# 명시적으로 index와 columns를 입력하지 않더라도 자동으로 index, columns가 생성
# numpy의 배열 데이터를 입력해 생성한 DataFrame 데이터의 예
import numpy as np
data_list = np.array([[10,20,30], [40,50,60], [70,80,90]])
print(data_list)
# [[10 20 30]
# [40 50 60]
# [70 80 90]]
d2 = pd.DataFrame(data_list)
print(d2)
# 0 1 2
# 0 10 20 30
# 1 40 50 60
# 2 70 80 90
# data뿐만 아니라 index와 columns도 지정한 예
data = np.array([[1,2,3], [4,5,6], [7,8,9], [10,11,12]]) # values
index_data = pd.date_range('2019-09-01', periods=4)
columns_list = ['A', 'B', 'C']
d3 = pd.DataFrame(data=data, index=index_data, columns=columns_list)
print(d3)
# A B C
# 2019-09-01 1 2 3
# 2019-09-02 4 5 6
# 2019-09-03 7 8 9
# 2019-09-04 10 11 12
# 딕셔너리 타입으로 2차원 데이터를 입력한 예
table_data = {'연도': [2015, 2016, 2016, 2017, 2017],
'지사': ['한국', '한국', '미국', '한국','미국'],
'고객 수': [200, 250, 450, 300, 500]}
d4 = pd.DataFrame(table_data)
print(d4)
# 연도 지사 고객 수
# 0 2015 한국 200
# 1 2016 한국 250
# 2 2016 미국 450
# 3 2017 한국 300
# 4 2017 미국 500
# 리스트나 넘파이 배열은 행 단위로 입력이 되고, 딕셔너리는 열 단위로 입력됨
# 입력시 키의 순서를 지정할 수도 있음
d5 = pd.DataFrame(table_data, columns=['지사', '고객 수', '연도'])
print(d5)
# 지사 고객 수 연도
# 0 한국 200 2015
# 1 한국 250 2016
# 2 미국 450 2016
# 3 한국 300 2017
# 4 미국 500 2017
# DataFrame 데이터에서 index, columns, values을 각각 구한 예
print(d5.index) # RangeIndex(start=0, stop=5, step=1)
print(d5.columns) # Index(['지사', '고객 수', '연도'], dtype='object')
print(d5.values)
# [['한국' 200 2015]
# ['한국' 250 2016]
# ['미국' 450 2016]
# ['한국' 300 2017]
# ['미국' 500 2017]]
4. 데이터 연산
# pandas의 Series()와 DataFrame()으로 생성된 데이터 끼리는 사칙연산이 가능
# Series()로 생성한 데이터의 예
import pandas as pd
s1 = pd.Series([1,2,3,4,5])
s2 = pd.Series([10, 20, 30, 40, 50])
print(s1 + s2)
# 0 11
# 1 22
# 2 33
# 3 44
# 4 55
# dtype: int64
print(s2-s1)
# 0 9
# 1 18
# 2 27
# 3 36
# 4 45
# dtype: int64
print(s1 * s2)
# 0 10
# 1 40
# 2 90
# 3 160
# 4 250
# dtype: int64
print(s2/s1)
# 0 10.0
# 1 10.0
# 2 10.0
# 3 10.0
# 4 10.0
# dtype: float64
# 파이썬의 리스트와 numpy의 배열과 달리 pandas의 데이터 끼리는 서로 크기가 달라도 연산이 가능
# 이 경우 연산을 할 수 있는 항목과 연산을 수행
s3 = pd.Series([1,2,3,4])
s4 = pd.Series([10, 20, 30, 40, 50])
print(s3 + s4)
# 0 11.0
# 1 22.0
# 2 33.0
# 3 44.0
# 4 NaN
# dtype: float64
print(s4-s3)
# 0 9.0
# 1 18.0
# 2 27.0
# 3 36.0
# 4 NaN
# dtype: float64
print(s3 * s4)
# 0 10.0
# 1 40.0
# 2 90.0
# 3 160.0
# 4 NaN
# dtype: float64
print(s4/s3)
# 0 10.0
# 1 10.0
# 2 10.0
# 3 10.0
# 4 NaN
# dtype: float64
# s3와 s4의 데이터 크기가 달라서, 연산할 수 있는 부분만 연산한 결과를 보여주고 연산할 수 없는 부분은 NaN으로 표시
# DataFrame()으로 생성한 데이터의 예
table_data1 = {'A': [1,2,3,4,5],
'B': [10,20,30,40,50],
'C': [100,200,300,400,500]}
df1 = pd.DataFrame(table_data1)
print(df1)
# A B C
# 0 1 10 100
# 1 2 20 200
# 2 3 30 300
# 3 4 40 400
# 4 5 50 500
table_data2 = {'A': [6,7,8],
'B': [60, 70, 80],
'C': [600, 700, 800]}
df2 = pd.DataFrame(table_data2)
print(df2)
# A B C
# 0 6 60 600
# 1 7 70 700
# 2 8 80 800
# 두 개의 DataFrame 데이터 df1과 df2는 길이가 같지 않음
# 길이가 같지 않더라도 연산이 가능
print(df1 + df2)
# A B C
# 0 7.0 70.0 700.0
# 1 9.0 90.0 900.0
# 2 11.0 110.0 1100.0
# 3 NaN NaN NaN
# 4 NaN NaN NaN
# Series와 마찬가지로 DataFrame도 연산할 수 있는 항목 끼리만 연산하고 그렇지 못한 항목은 NaN으로 표시
# 공간은 차지하되 데이터는 없는 상태
# pandas에는 데이터의 통계 분석을 위한 다양한 메서드가 있어서 데이터의 총합, 평균, 표준 편차들을 쉽게 구할 수 있음
# 2012년 부터 2016년 까지 우리나라의 계절별 강수량(단위 mm).
table_data3 = {'봄': [256.5, 264.3, 215.9, 223.2, 312.8],
'여름': [770.6, 567.5, 599.8, 387.1, 446.2],
'가을': [363.5, 231.2, 293.1, 247.7, 381.6],
'겨울': [139.3, 59.9, 76.9, 109.1, 108.1]}
columns_list = ['봄', '여름', '가을', '겨울']
index_list = ['2012', '2013', '2014','2015','2016']
df3 = pd.DataFrame(index = index_list, columns=columns_list, data = table_data3)
print(df3)
# 봄 여름 가을 겨울
# 2012 256.5 770.6 363.5 139.3
# 2013 264.3 567.5 231.2 59.9
# 2014 215.9 599.8 293.1 76.9
# 2015 223.2 387.1 247.7 109.1
# 2016 312.8 446.2 381.6 108.1
# pandas에서 제공하는 통계 메서드는 원소의 합을 구하는 sum(), 평균을 구하는 mean(),
# 표준편차를 구하는 std(), 분산을 구하는 var(), 최솟값을 구하는 min(), 최댓값을 구하는 max(),
# 각 원소의 누적 합을 구하는 cumsum(), 각 원소의 누적 곱을 구하는 cumprod() 등이 있음
# -> numpy의 메서드 이름이 동일
print(df3.std()) # 계절별 강수량 표준편차
# 봄 38.628267
# 여름 148.888895
# 가을 67.358496
# 겨울 30.925523
# dtype: float64
# 연도별로 평균 강수량과 표준 편차를 구할 경우엔 연산의 방향 설정을 위해 axis 인자를 추가
# 인자 axis가 0이면 DataFrame의 values에서 열별로 연산을 수행하고
# 1이면 행별로 연산. axis 인자를 설정하지 ㅇ낳으면 기본값을 0으로 설정
print(df3.mean(axis=1))
# 2012 382.475
# 2013 280.725
# 2014 296.425
# 2015 241.775
# 2016 312.175
# dtype: float64
print(df3.std(axis=1))
# 2012 274.472128
# 2013 211.128782
# 2014 221.150739
# 2015 114.166760
# 2016 146.548658
# dtype: float64
# 평균과 표준편차를 개별적으로 구했으나 describe()을 이용하면
# 평균, 표준편차, 최솟값과 최댓값 등을 한 번에 구할 수 있음
# 25% / 50% / 75% : 백분위수의 각 지정으로, 분포를 반영해 평균을 보완하는 목적으로 사용
print(df3.describe())
# 봄 여름 가을 겨울
# count 5.000000 5.000000 5.000000 5.000000
# mean 254.540000 554.240000 303.420000 98.660000
# std 38.628267 148.888895 67.358496 30.925523
# min 215.900000 387.100000 231.200000 59.900000
# 25% 223.200000 446.200000 247.700000 76.900000
# 50% 256.500000 567.500000 293.100000 108.100000
# 75% 264.300000 599.800000 363.500000 109.100000
# max 312.800000 770.600000 381.600000 139.300000
5. 데이터파일 읽기
import pandas as pd
# 1) 표 형식의 데이터 파일을 읽기
# 판다스에서 csv파일을 읽을 때는 read_csv() 메서드 이용
# DataFrame_data = pd.read_csv(file_name [, options])
df1 = pd.read_csv('./input/sea_rain1.csv')
print(df1)
# 연도 동해 남해 서해 전체
# 0 1996 17.4629 17.2288 14.4360 15.9067
# 1 1997 17.4116 17.4092 14.8248 16.1526
# 2 1998 17.5944 18.0110 15.2512 16.6044
# 3 1999 18.1495 18.3175 14.8979 16.6284
# 4 2000 17.9288 18.1766 15.0504 16.6178
print(df1.dtypes)
# 연도 int64
# 동해 float64
# 남해 float64
# 서해 float64
# 전체 float64
# dtype: object
# 파이썬에서 텍스트파일을 생성하면 기본 문자 인코딩이 'utf-8'이고, 메모장의 경우 기본 문자 인코딩이 'cp949'.
# sea_rain1_from_notepad.csv 파일을 경우 메모장으로 생성해서, 인코딩이 'cp949'이므로 에러가 남
d2 = pd.read_csv('./input/sea_rain1_from_notepad.csv', encoding='cp949')
print(d2)
# 연도 동해 남해 서해 전체
# 0 1996 17.4629 17.2288 14.4360 15.9067
# 1 1997 17.4116 17.4092 14.8248 16.1526
# 2 1998 17.5944 18.0110 15.2512 16.6044
# 3 1999 18.1495 18.3175 14.8979 16.6284
# 4 2000 17.9288 18.1766 15.0504 16.6178
# seq_rain1_space.txt 파일의 경우 콤마가 아니라 공백(빈칸)으로 구분된 경우
# sep 옵션을 이용해서 구분차가 콤마가 아니라 공백임을 지정
# 아래 처럼 확장자가 txt라도 read_csv()로 읽을 수 있음
d3 = pd.read_csv('./input/sea_rain1_space.txt', sep=' ')
print(d3)
# 연도 동해 남해 서해 전체
# 0 1996 17.4629 17.2288 14.4360 15.9067
# 1 1997 17.4116 17.4092 14.8248 16.1526
# 2 1998 17.5944 18.0110 15.2512 16.6044
# 3 1999 18.1495 18.3175 14.8979 16.6284
# 4 2000 17.9288 18.1766 15.0504 16.6178
# read_csv()로 텍스트 파일을 읽어오면 index가 자동으로 지정
# 이 때 자동으로 생성된 index 말고 데이터 파일에서 특정 열 column을 index로 선택하려면 'index_col=열_이름'을 추가
c4 = pd.read_csv('./input/sea_rain1.csv', index_col='연도')
print(c4)
# 동해 남해 서해 전체
# 연도
# 1996 17.4629 17.2288 14.4360 15.9067
# 1997 17.4116 17.4092 14.8248 16.1526
# 1998 17.5944 18.0110 15.2512 16.6044
# 1999 18.1495 18.3175 14.8979 16.6284
# 2000 17.9288 18.1766 15.0504 16.6178
6. 데이터 파일 쓰기
# to_csv()을 이용하면 DataFrame 형식의 데이터를 텍스트 파일로 저장
# DataFrame_data.to_csv(file_name [, options])
# file_name은 텍스트 파일 이름으로 경로를 포함할 수 있음
# 선택사항인 options에는 구분자와 문자의 인코딩 방식 등을 지정할 수 있고, 지정하지 않으면 구분자는 콤마가 되고, 문자의 인코딩 방식은 'utf-8'이 됨
import pandas as pd
# to_csv()을 이용하면 DataFrame 형식의 데이터를 텍스트 파일로 저장
# DataFrame_data.to_csv(file_name [, options])
# file_name은 텍스트 파일 이름으로 경로를 포함할 수 있음
# 선택사항인 options에는 구분자와 문자의 인코딩 방식 등을 지정할 수 있고, 지정하지 않으면 구분자는 콤마가 되고, 문자의 인코딩 방식은 'utf-8'이 됨
# 네 명의 몸무게 Weight와 키 Height 데이터를 DataFrame 형식으로 생성
df_WH = pd.DataFrame({'Weight': [62, 67, 55, 74],
'Height': [165, 177, 160, 180]},
index=['ID_1', 'ID_2', 'ID_3', 'ID_4'])
print(df_WH)
# Weight Height
# ID_1 62 165
# ID_2 67 177
# ID_3 55 160
# ID_4 74 180
df_WH.index.name = 'User'
print(df_WH)
# Weight Height
# User
# ID_1 62 165
# ID_2 67 177
# ID_3 55 160
# ID_4 74 180
# 파일로 저장하기 전에 몸무게와 키를 이용해 체질량 지수 BMI를 구해서 추가
# 체질량 지수 Body Mass Index는 몸무게 Kg
# BMI = W / H의 제곱
# 키의 경우 데이터가 cm단위여서 m 단위로 변경
bmi =df_WH['Weight'] / (df_WH['Height']/100) ** 2
print(bmi)
# User
# ID_1 22.773186
# ID_2 21.385936
# ID_3 21.484375
# ID_4 22.839506
# dtype: float64
# 체질량 지수를 df_WH에 추가.
df_WH['BMI'] = bmi
print(df_WH)
# Weight Height BMI
# User
# ID_1 62 165 22.773186
# ID_2 67 177 21.385936
# ID_3 55 160 21.484375
# ID_4 74 180 22.839506
# csv 파일 저장
df_WH.to_csv('./output/save_dataFrame.csv')
# DataFrame 데이터를 파일로 저장할 때 옵션을 지정하는 예
# 한 회사의 제품별 판매 가격과 판매량 정보가 있는 DataFrame 데이터를 생성
df_pr = pd.DataFrame({'판매가격' : [2000, 3000, 5000, 10000],
'판매량' : [32, 53, 40, 25]},
index=['P1001', 'P1002', 'P1003', 'P1004'])
df_pr.index.name = '제품번호'
print(df_pr)
# 판매가격 판매량
# 제품번호
# P1001 2000 32
# P1002 3000 53
# P1003 5000 40
# P1004 10000 25
file_name = './output/save_DataFrame_cp949.txt'
df_pr.to_csv(file_name, sep=' ', encoding='cp949')
7. 판다스 데이터 확인하기
- 판다스에는 데이터 분석에 유용한 여러 가지 메서드와 속성이 미리 정의되어 있음
import pandas as pd
# 1) DataFrame 만들기
# csv 파일 불러오기
# csv 파일을 불러와서 데이터프레임을 생성
df = pd.read_csv('./input/weather.csv')
print(df) # 주피터 노트북에서 df만 기입 시 데이터를 모두 읽음
# date temp max_wind mean_wind
# 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]
# 2) df.shape
# shape 속성을 이용하면 데이터의 (행, 열) 크기를 확인할 수 있음
# 행, 열 크기 확인하기
print(df.shape) # (3653, 4)
print(df.shape[0]) # 3653
# 3) df.info()
# info()메서드는 데이터에 대한 전반적인 정보를 나타냄
# df를 구성하는 행과 열의 크기, 컬럼명, 컬럼을 구성한느 값의 자료형을 출력해줌
df.info()
# <class 'pandas.core.frame.DataFrame'>
# RangeIndex: 3653 entries, 0 to 3652
# Data columns (total 4 columns):
# # Column Non-Null Count Dtype
# --- ------ -------------- -----
# 0 date 3653 non-null object
# 1 temp 3653 non-null float64
# 2 max_wind 3649 non-null float64
# 3 mean_wind 3647 non-null float64
# dtypes: float64(3), object(1)
# memory usage: 114.3+ KB
# -> 데이터 개수 n=3653 entry, 행 인덱스 번호 0 to 3652
# 열 변수 출력 형식 : 실수 float, 문자열 object
# 결측치 개수가 나타남 : max_wind, mean_wind 변수에 결측치가 있음
# 4) df.head(), df.tail()
# 데이터를 잘 불러 왔는지 확인하기 위해 앞 부분과 마지막 부분을 확인
# 상위 n행 살펴보기
print(df.head()) # 숫자 기입 시, 개수 행 출력. 기본 = 5
# date temp max_wind mean_wind
# 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
# 하위 n행 살펴보기
print(df.tail())
# date temp max_wind mean_wind
# 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
# head()는 상위 5개 행을 출력하고, tail()은 하위 5개 행을 출력함
# 괄호() 안에 원하는 숫자를 넣으면 그 숫자만큼 행을 출력
# 5) df.index, df.columns
# 인덱스(행 이름)과 열의 레이블(칼럼 이름)을 출력할 때 사용
# 인덱스 출력
print(df.index) # RangeIndex(start=0, stop=3653, step=1)
# 데이터프레임의 인덱스(행 이름)을 반환. 인덱스를 따로 지정하지 않았기 때문에 0부터 시작하는 인덱스가 부여.
# 칼럼 출력
print(df.columns)
# Index(['date', 'temp', 'max_wind', 'mean_wind'], dtype='object')
# 해당 데이터프레임을 구성하는 컬럼명을 확인할 수 있음
# 컬럼명을 변경할 때도 유용하게 사용
# 6) df.describe()
# 데이터의 컬럼별 요약 통계량을 나타냄
# 또한 mean(), max() 등 개별 함수를 사용하여 통계량을 계산 할 수 있음
# 요약 통계량 확인하기
print(df.describe())
# temp max_wind mean_wind
# count 3653.000000 3649.000000 3647.000000
# mean 12.942102 7.911099 3.936441
# std 8.538507 3.029862 1.888473
# min -9.000000 2.000000 0.200000
# 25% 5.400000 5.700000 2.500000
# 50% 13.800000 7.600000 3.600000
# 75% 20.100000 9.700000 5.000000
# max 31.300000 26.000000 14.900000
# 7) df.sort_values()
# 데이터를 크기 순으로 정렬
# 형식
# DataFrame.sort_values(by=['정렬변수1', '정렬변수2'...], ascending=True, inplace=False)
# by=[] : by=을 사용하지 않아도 됨
# ascending=True : True가 기본 값이고 오름차순 정렬. 내림차순 정렬일 경우에는 False 사용.
# inplace=False : True 이면 정렬 결과가 동일 데이터프레임 이름으로 저장. 기본 값을 False.
# 최대 풍속 max_wind 컬럼의 값의 크기에 따라 오름차순 정렬
# 값이 같을 경우 인덱스값이 큰 순서대로 정렬
print(df.sort_values(['max_wind']))
# date temp max_wind mean_wind
# 1514 2014-09-23 20.7 2.0 1.0
# 1134 2013-09-08 20.4 2.1 0.8
# 421 2011-09-26 18.7 2.1 0.3
# 1512 2014-09-21 20.4 2.2 1.2
# 1005 2013-05-02 7.1 2.2 0.8
# ... ... ... ... ...
# 2988 2018-10-06 19.4 26.0 7.0
# 559 2012-02-11 -0.7 NaN NaN
# 560 2012-02-12 0.4 NaN NaN
# 561 2012-02-13 4.0 NaN NaN
# 3183 2019-04-19 7.8 NaN 2.3
#
# [3653 rows x 4 columns]
# 최대 풍속 max wind 컬럼의 값의 크기에 따라 내림차순 정렬
print(df.sort_values(by=['max_wind'], ascending=False))
# date temp max_wind mean_wind
# 2988 2018-10-06 19.4 26.0 7.0
# 3340 2019-09-23 15.0 25.8 11.0
# 1850 2015-08-25 20.1 25.3 14.9
# 3339 2019-09-22 15.7 23.1 11.9
# 1851 2015-08-26 17.4 22.6 8.1
# ... ... ... ... ...
# 1514 2014-09-23 20.7 2.0 1.0
# 559 2012-02-11 -0.7 NaN NaN
# 560 2012-02-12 0.4 NaN NaN
# 561 2012-02-13 4.0 NaN NaN
# 3183 2019-04-19 7.8 NaN 2.3
#
# [3653 rows x 4 columns]
# 8) df.value_count()
# 범주형 변수의 빈도분석 결과를 출력. 즉 어떤 컬럼의 unique value(고유값)들의 개수를 구함
bank = pd.read_csv('./input/bank.csv')
print(bank.head())
# job education balance duration y
# 0 management tertiary 2143 261 no
# 1 technician secondary 265 348 no
# 2 blue-collar secondary -7 365 no
# 3 technician secondary -3 1666 no
# 4 technician secondary -103 145 no
# 빈도 분석 출력하기
print(bank['job'].value_counts())
# job
# management 1560
# blue-collar 1499
# technician 1206
# admin. 834
# services 661
# retired 351
# self-employed 256
# entrepreneur 239
# unemployed 223
# housemaid 208
# student 153
# Name: count, dtype: int64
print(bank['education'].value_counts())
# education
# secondary 3745
# tertiary 2178
# primary 1038
# Name: count, dtype: int64
print(bank['job'].value_counts(ascending=True)) # 오름차순 정렬
# job
# student 153
# housemaid 208
# unemployed 223
# entrepreneur 239
# self-employed 256
# retired 351
# services 661
# admin. 834
# technician 1206
# blue-collar 1499
# management 1560
# Name: count, dtype: int64
# 9) df.unique()
# 데이터가 무엇으로 구성되어 있는지 보고싶을 때 사용. 열의 고유값을 볼 수 있음
# column의 고유값 출력하기
print(bank['job'].unique())
# ['management' 'technician' 'blue-collar' 'retired' 'services' 'admin.'
# 'entrepreneur' 'self-employed' 'unemployed' 'student' nan 'housemaid']
# 음식적이 많은 음식골목명을 순서대로 출력
daegu_food = pd.read_csv('./input/daegufood_street.csv')
daegu_food_summary = daegu_food['음식골목명'].value_counts()
daegu_food_summary.to_csv('./output/daegufood_steet_summary.csv')
sangga_info_kb = pd.read_csv('./input/소상공인시장진흥공단_상가(상권)정보/소상공인시장진흥공단_상가(상권)정보_경북_202312.csv')
sangga_info_kb['시군구명'].value_counts().to_csv('./output/gk_store_01.csv')
sangga_info_kb['시군구명'].value_counts(ascending=True).head().to_csv('./output/gk_store_02.csv')
sangga_info_kb['상권업종대분류명'].value_counts(ascending=True).head(3).to_csv('./output/gk_store_03.csv')
8. 판다스 데이터 선택하기
# Pandas DataFrame으로 부터 데이터를 선택하는 다양한 방법
import pandas as pd
# 1) 열 선택하기
# DataFrame의 하나의 열을 선택하면 하나의 Series를 만듬
# df['컬럼명']는 df.컬럼명과 같음. 단, 이 방법을 사용하려면 열 이름이 숫자로 시작하지 않고 공백이나 특수 문자 등을 포함하지 않는 등의
# 조건을 만족해야함
# iloc() 및 loc() 메서드를 사용하여 려러 열을 선택할 수도 있음
# 단일 컬럼 선택하기
df = pd.read_csv('./input/weather.csv')
print(df['temp'])
# 0 28.7
# 1 25.2
# 2 22.1
# 3 25.3
# 4 27.2
# ...
# 3648 22.1
# 3649 21.9
# 3650 21.6
# 3651 22.9
# 3652 25.7
# Name: temp, Length: 3653, dtype: float64
print(df.temp)
# 0 28.7
# 1 25.2
# 2 22.1
# 3 25.3
# 4 27.2
# ...
# 3648 22.1
# 3649 21.9
# 3650 21.6
# 3651 22.9
# 3652 25.7
# Name: temp, Length: 3653, dtype: float64
# 여러 컬럼 선택하기
# 추출할 때 열 이름을 리스트에 저장한 다음 []에 전달하면 여러 열을 선택할 수 있음
print(df[['date', 'temp']])
# date temp
# 0 2010-08-01 28.7
# 1 2010-08-02 25.2
# 2 2010-08-03 22.1
# 3 2010-08-04 25.3
# 4 2010-08-05 27.2
# ... ... ...
# 3648 2020-07-27 22.1
# 3649 2020-07-28 21.9
# 3650 2020-07-29 21.6
# 3651 2020-07-30 22.9
# 3652 2020-07-31 25.7
#
# [3653 rows x 2 columns]
# 여러 컬럼 선택하기 : loc
# 열 이름을 사용하여 열을 선택하려는 경우 loc를 사용
# df.loc[행 인덱싱 값, 열 인덱싱 값]
df.loc[:, ['date', 'temp']]
# date temp
# 0 2010-08-01 28.7
# 1 2010-08-02 25.2
# 2 2010-08-03 22.1
# 3 2010-08-04 25.3
# 4 2010-08-05 27.2
# ... ... ...
# 3648 2020-07-27 22.1
# 3649 2020-07-28 21.9
# 3650 2020-07-29 21.6
# 3651 2020-07-30 22.9
# 3652 2020-07-31 25.7
#
# [3653 rows x 2 columns]
# 여러 컬럼 선택하기 : iloc
# 열 인덱스를 사용하여 추출
# df.iloc[행 인덱스, 열 인덱스]
print(df.iloc[:, [0,1]])
# date temp
# 0 2010-08-01 28.7
# 1 2010-08-02 25.2
# 2 2010-08-03 22.1
# 3 2010-08-04 25.3
# 4 2010-08-05 27.2
# ... ... ...
# 3648 2020-07-27 22.1
# 3649 2020-07-28 21.9
# 3650 2020-07-29 21.6
# 3651 2020-07-30 22.9
# 3652 2020-07-31 25.7
#
# [3653 rows x 2 columns]
# 2) 행 선택하기
# 특정 행 범위 선택하기
# 인덱스 숫자를 사용하면 행을 슬라이싱할 수 있음
print(df[0:3])
# date temp max_wind mean_wind
# 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) 레이블로 선택하기 df.loc
# 특정 날짜에 해당하는 열 선택
df.index = df['date'] # 인덱스 값으로 df['date']을 설정
print(df)
# date temp max_wind mean_wind
# date
# 2010-08-01 2010-08-01 28.7 8.3 3.4
# 2010-08-02 2010-08-02 25.2 8.7 3.8
# 2010-08-03 2010-08-03 22.1 6.3 2.9
# 2010-08-04 2010-08-04 25.3 6.6 4.2
# 2010-08-05 2010-08-05 27.2 9.1 5.6
# ... ... ... ... ...
# 2020-07-27 2020-07-27 22.1 4.2 1.7
# 2020-07-28 2020-07-28 21.9 4.5 1.6
# 2020-07-29 2020-07-29 21.6 3.2 1.0
# 2020-07-30 2020-07-30 22.9 9.7 2.4
# 2020-07-31 2020-07-31 25.7 4.8 2.5
#
# [3653 rows x 4 columns]
print(df.loc['2010-08-01', ['temp', 'mean_wind']])
# temp 28.7
# mean_wind 3.4
# Name: 2010-08-01, dtype: object
# 4) 위치로 선택하기 df.iloc
# iloc[n]과 같이 정수를 입력하면 해당 행을 선택. iloc 이후에 붙은 숫자 3은
# (위에서 0부터 시작) 4번째 행이라는 뜻
# 특정 행 선택
print(df.iloc[3])
# date 2010-08-04
# temp 25.3
# max_wind 6.6
# mean_wind 4.2
# Name: 2010-08-04, dtype: object
# 특정 행과 열 선택 : 슬라이싱
print(df.iloc[1:3, 0:2])
# date temp
# date
# 2010-08-02 2010-08-02 25.2
# 2010-08-03 2010-08-03 22.1
# 5) 불 인덱싱
# 하나의 열의 값을 기준으로 데이터를 선택할 수 있음
# df[df.A > 0]은 df로 부터 A열이 0보다 큰 데이터를 보여줌.
# 조건에 맞는 데이터를 추출
w = df['temp'] > 30
print(w)
# date
# 2010-08-01 False
# 2010-08-02 False
# 2010-08-03 False
# 2010-08-04 False
# 2010-08-05 False
# ...
# 2020-07-27 False
# 2020-07-28 False
# 2020-07-29 False
# 2020-07-30 False
# 2020-07-31 False
# Name: temp, Length: 3653, dtype: bool
print(df[w])
# date temp max_wind mean_wind
# date
# 2013-08-08 2013-08-08 31.3 7.8 4.6
# 2013-08-09 2013-08-09 30.6 9.9 6.4
# 2013-08-10 2013-08-10 30.6 7.4 3.8
# 2018-07-23 2018-07-23 30.5 6.5 1.6
# 2018-08-04 2018-08-04 30.3 5.8 3.0
# 기온 temp이 30도 이상인 모든 데이터를 추출. 넘파이의 불 인덱싱과 동일한 문법
print(df[df['temp']>30])
# date temp max_wind mean_wind
# date
# 2013-08-08 2013-08-08 31.3 7.8 4.6
# 2013-08-09 2013-08-09 30.6 9.9 6.4
# 2013-08-10 2013-08-10 30.6 7.4 3.8
# 2018-07-23 2018-07-23 30.5 6.5 1.6
# 2018-08-04 2018-08-04 30.3 5.8 3.0
# 최고로 더웠던 날의 모든 정보를 추출
w = df['temp'] == df['temp'].max()
print(df[w])
# date temp max_wind mean_wind
# date
# 2013-08-08 2013-08-08 31.3 7.8 4.6
# 조건이 2개 이상인 겨우
# 기온이 30도 이상이고, 최대 풍속이 9이상인 데이터
w = (df['temp']>= 30) & (df['max_wind'] >= 9)
print(df[w])
# date temp max_wind mean_wind
# date
# 2013-08-09 2013-08-09 30.6 9.9 6.4
9. 무료 웹 호스팅
무료홈페이지 | 무료호스팅 | 닷홈
닷홈은 도메인, 무료호스팅, 무료홈페이지, 웹호스팅, 웹메일, SSL보안인증서, 서버호스팅 등 호스팅 서비스를 제공하고 있습니다.
www.dothome.co.kr
- 닷홈 접속 > 회원가입
- 웹 호스팅 > 무료호스팅 클릭
- 기본사양 신청하기
- FTP 아이디 변경 나중에 힘들 수 있음
- 이메일 인증까지 하면 호스팅 세팅 완료
10. 판다스 결측 데이터 처리하기
# pandas는 누락된 데이터를 표시할 때 NaN(Not a Number)으로 표기하며, 연산에는 포함되지 않음
import pandas as pd
df = pd.read_csv('./input/weather.csv')
print(df.head())
# date temp max_wind mean_wind
# 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
df.info()
# <class 'pandas.core.frame.DataFrame'>
# RangeIndex: 3653 entries, 0 to 3652
# Data columns (total 4 columns):
# # Column Non-Null Count Dtype
# --- ------ -------------- -----
# 0 date 3653 non-null object
# 1 temp 3653 non-null float64
# 2 max_wind 3649 non-null float64
# 3 mean_wind 3647 non-null float64
# dtypes: float64(3), object(1)
# memory usage: 114.3+ KB
#isnull은 결측 데이터라면 True 반환. 유효한 데이터가 존재한다면 False반환
# ina(), isnumm()은 기능적으로 동일
# 결측 에이터
# 2) 결측 데이터 삭제하기
# 결측 데이터를 다루는 가장 간단한 방법은 결측 데이터를 가진 해잉나 열을 삭제
# DataFrame.dropna(axis, how, thresh, subset, inplace)
# axis : 축을 행 또는 열로 결정
# 0 또는 'index'이면 누락된 값이 포함된 행을 삭제
# 1 또는 'columns'이면 누락된 값이 포함된 열을 삭제
# 기본적으로 값은 0
# how : any는 null 값이 있는 경우 행 또는 열을 삭제
# all은 모든 값이 누락된 경우 행 또는 열을 삭제
# 기본값은 any
# inplace : 데이터프레임에 나온 값을 저장할 것인지를 설정하는 변수로 기본적으로 값은 False
# 결측 데이터가 있는 행 삭제 후 확인
df2 = df.dropna() # 옵션을 지정하지 않아서 행기준, NoN가 하나라도 있은 경우에 삭제
print(df2.isnull().sum())
# temp 0
# max_wind 0
# mean_wind 0
# dtype: int64
# 행 데이터 중 어느 한 변수에도 결측치가 있는 경우 삭제되므로
# 향후 제거한 데이터프레임을 사용하려면 다른 이름으로 저장해야 함
print(df.isnull().sum())
# temp 0
# max_wind 4
# mean_wind 6
# dtype: int64
# 3) 결측 데이터 대체하기
# 결측 데이터 대체하기 : 평균값으로 대체
df['max_wind'].fillna(df['max_wind'].mean(), inplace=True)
df['mean_wind'].fillna(df['mean_wind'].mean(), inplace=True)
# fillna() 같은 데이터를 특정 값으로 채움. inplace를 True로 설정해 원본 데이터를 수정
# 결측 데이터 대체 후 확인
print(df.isna().sum())
# temp 0
# max_wind 0
# mean_wind 0
# dtype: int64
11. 판다스 데이터 가공하기
- EXCEL 파일을 읽기 위해 'openpyxl' 라이브러리 추가 설치 ( 세팅 > py 인터프리터 > + )
# 엑셀 파일 dust1.xlxs 파일을 불러와서 데이터프레임을 생성
import datetime
import pandas as pd
dust = pd.read_excel('./input/dust1.xlsx')
print(dust.head())
# 지역 망 측정소코드 측정소명 ... NO2 PM10 PM25 주소
# 0 서울 송파구 도시대기 111273 송파구 ... 0.066 50 18 서울 송파구 백제고분로 236
# 1 서울 송파구 도시대기 111273 송파구 ... 0.058 48 20 서울 송파구 백제고분로 236
# 2 서울 송파구 도시대기 111273 송파구 ... 0.055 44 20 서울 송파구 백제고분로 236
# 3 서울 송파구 도시대기 111273 송파구 ... 0.055 40 20 서울 송파구 백제고분로 236
# 4 서울 송파구 도시대기 111273 송파구 ... 0.053 38 17 서울 송파구 백제고분로 236
#
# [5 rows x 12 columns]
# 1) 컬럼(변수) 삭제/생성하기
# 데이터 분석에 필요없는 '지역', '망', '측정소코드' 컬럼을 삭제하고 특정값으로 새로운 컬럼을 생성
dust = dust.drop(['지역', '망', '측정소코드'], axis=1)
# axis의 기본값이 axis=0으로 행 삭제가 됨. 컬럼을 삭제하기 위해서는 axis=1을 반드시 사용
print(dust.head())
# 측정소명 측정일시 SO2 CO O3 NO2 PM10 PM25 주소
# 0 송파구 2021040101 0.004 1.0 0.002 0.066 50 18 서울 송파구 백제고분로 236
# 1 송파구 2021040102 0.004 0.8 0.002 0.058 48 20 서울 송파구 백제고분로 236
# 2 송파구 2021040103 0.004 0.8 0.002 0.055 44 20 서울 송파구 백제고분로 236
# 3 송파구 2021040104 0.003 0.8 0.002 0.055 40 20 서울 송파구 백제고분로 236
# 4 송파구 2021040105 0.004 0.8 0.002 0.053 38 17 서울 송파구 백제고분로 236
# 새로운 칼럼 생성
dust['city'] = '서울'
print(dust.head())
# 측정소명 측정일시 SO2 CO O3 NO2 PM10 PM25 주소 city
# 0 송파구 2021040101 0.004 1.0 0.002 0.066 50 18 서울 송파구 백제고분로 236 서울
# 1 송파구 2021040102 0.004 0.8 0.002 0.058 48 20 서울 송파구 백제고분로 236 서울
# 2 송파구 2021040103 0.004 0.8 0.002 0.055 44 20 서울 송파구 백제고분로 236 서울
# 3 송파구 2021040104 0.003 0.8 0.002 0.055 40 20 서울 송파구 백제고분로 236 서울
# 4 송파구 2021040105 0.004 0.8 0.002 0.053 38 17 서울 송파구 백제고분로 236 서울
# 2) 컬럼 이름 변경
# 컬럼 이름 변경 방법
# 1) DataFrame.columns=['새이름1', '새이름2', ...]
# 전체 변수 이름을 재설정
# 변수명을 차례대로 재설정. 변수가 많은 경우 적절하지 않음.
# 2) DataFrame.rename(columns={'기존이름':'새이름'}, inplace=True)
# 원하는 변수이름만 수정
# 딕셔너리 구조로 정의. 즉 이전 열이름을 키로 지정하고 새 이름으로 값으로 지정
dust.rename(columns={'측정소명':'name','측정일시':'date','주소':'addr'}, inplace=True)
print(dust.columns)
# Index(['name', 'date', 'SO2', 'CO', 'O3', 'NO2', 'PM10', 'PM25', 'addr',
# 'city'],
# dtype='object')
# 3) 데이터 형변환
print(dust.dtypes)
# name object
# date int64
# SO2 float64
# CO float64
# O3 float64
# NO2 float64
# PM10 int64
# PM25 int64
# addr object
# city object
# dtype: object
# date 칼럼이 숫자형(int)로 저장되어 있음
# 숫자 형식은 문자 형식으로 변환
# astype(str)으로 문자열 형식으로 변환하고 데이터 길이를 날짜 형식 8자리에 적합하도록 str.slice()를 사용하여 첫 8자리만 저장
# (문자열 데이터를 숫자 형식으로 바꾸는 경우는 .astype(int) 사용.)
# 숫자 int형을 문자열로 변환
dust['date'] = dust['date'].astype(str)
dust['date'] = dust['date'].str.slice(0, 8)
print(dust.head())
# name date SO2 CO O3 NO2 PM10 PM25 addr city
# 0 송파구 20210401 0.004 1.0 0.002 0.066 50 18 서울 송파구 백제고분로 236 서울
# 1 송파구 20210401 0.004 0.8 0.002 0.058 48 20 서울 송파구 백제고분로 236 서울
# 2 송파구 20210401 0.004 0.8 0.002 0.055 44 20 서울 송파구 백제고분로 236 서울
# 3 송파구 20210401 0.003 0.8 0.002 0.055 40 20 서울 송파구 백제고분로 236 서울
# 4 송파구 20210401 0.004 0.8 0.002 0.053 38 17 서울 송파구 백제고분로 236 서울
print(dust.dtypes)
# name object
# date object
# SO2 float64
# CO float64
# O3 float64
# NO2 float64
# PM10 int64
# PM25 int64
# addr object
# city object
# dtype: object
# 날짜 형식 활용 : Series.dt.형식
# dust['year'] = dust['date'].dt.year
# dust['month'] = dust['date'].dt.year
# dust['day'] = dust['date'].dt.day
# print(dust.head())
# 4) 데이터 병합하기
# merge() 함수는 두 데이터프레임을 각 데이터에 존재하는 고유값(key)을 기준으로 병합할 때 사용
# pd.merge(df_left, df_right, how='inner', on=None)
# 아무 옵션을 적용하지 않으면, on=None이므로 두 데이터의 공동 열이름(id)을 기준으로 inner(교집합) 조인을 하게 됨
# outer 옵션을 줘서 id를 기준으로 합치되, 어느 한쪽이라는 없는 데이터가 있는 경우 Nan 값이 지정
# 병합할 원본 데이터 확인하기
s1 = pd.read_excel('./input/nation.xlsx')
print(s1.head())
# 국적코드 성별 입국객수 증가수
# 0 A01 남성 125000 8000
# 1 A01 여성 130000 10000
# 2 A05 남성 300 10
# 3 A05 여성 200 50
# 4 A06 남성 158912 24486
s2 = pd.read_excel('./input/code.xlsx')
print(s2.head())
# 국적코드 국적명
# 0 A01 필리핀
# 1 A02 일본
# 2 A03 미국
# 3 A04 중국
# 4 A05 호주
# 데이터 병합하기 : 공통 컬럼을 기준
print(pd.merge(s1, s2, on='국적코드'))
# 국적코드 성별 입국객수 증가수 국적명
# 0 A01 남성 125000 8000 필리핀
# 1 A01 여성 130000 10000 필리핀
# 2 A05 남성 300 10 호주
# 3 A05 여성 200 50 호주
# 4 A06 남성 158912 24486 베트남
# 5 A06 여성 325000 63466 베트남
공부 과정을 정리한 것이라 내용이 부족할 수 있습니다.
부족한 내용은 추가 자료들로 보충해주시면 좋을 것 같습니다.
읽어주셔서 감사합니다 :)