Python 프로그래밍 및 Pandas 활용 실습(5)-2
2024. 1. 7. 17:50ㆍTIL
시계열 제어 - 날짜와 시간(Timestamp)
import pandas as pd
# 인자 입력
t1 = pd.Timestamp(year=2023, month=12, day=20,
hour=13, minute=45, second=56, microsecond=345111, nanosecond=237)
# 인자 생략 + 세계 협정시 Z
t1 = pd.Timestamp(2023,12,29,13,45,56,345111).tz_localize('UTC')
t1 = pd.Timestamp(2023,12,29,13,45,56,345111,'UTC')
# 날짜 표기로 한번에
t1 = pd.Timestamp('2023-12-29T13:45:56.345678901Z')
# T : 시간과 날짜 구분 표기(ISO 8601)
# Z : zulu, UTC 협정 세계시 표기
'+00:00' 또는 '-00:00'로 대체 표기도 가능
# 세계 협정시 조정
t1 = pd.Timestamp('2023-12-29T13:45:56.345+09:00')
# 객체 속성 접근/활용
t1.year # 2023
f"{t1.month}월 {t1.day}일"
t1.week # 52
.strftime()으로 날짜데이터를 string format화
# %X == %H:%M:%S
t1.strftime("%Y-%m-%d %H:%M:%S")
t1.strftime("%Y-%m-%d %X")
# Timestampe 사칙연산
t1 = pd.Timestamp('2022-01-01 12:34:56')
t2 = pd.Timestamp('2023-03-04 13:35:59')
t2 - t1 # Timedelta('427 days 01:01:03')
# 다양한 Timestamp 생성법
# 날짜 표기법으로 입력
texts = [
'2020-01-02',
'2022/01/02',
'2021.01.02',
'2023 Jan 02'
]
for t in texts:
print(pd.Timestamp(t))
# 세계 협정시 기준 : 1970.1.1 00:00부터의 ns로 입력
import time
time.time() # second
time.time_ns() # nanosecond
pd.Timestamp(ns)
pd.Timestamp(s, unit='s')
# pd.to_datetime()
# 문자열 또는 숫자를 날짜와 시간으로 변환하는 기능을 제공
# 날짜 인자 입력 방법은 위의 Timestamp()와 거의 같다.
for t in texts:
print(pd.to_datetime(t))
pd.to_datetime(texts[0])
ns = 1702731342736680500
pd.to_datetime(ns)
'''
Timestamp() == to_datetime() 인가?
1. 입력 데이터의 형식
-Timestamp()
문자열, 정수, datetime 객체 등 다양한 형식의 데이터를 입력
-to_datetime()
대체로 문자열 데이터를 입력(숫자도 받긴함).
일반적으로 날짜와 시간을 나타내는 문자열 형식을 입력으로 사용.
2. 유효성 검사
-Timestamp()
입력 데이터에 대한 추가적인 유효성 검사를 수행하지 않음
잘못된 형식의 데이터가 입력되면 에러 발생.
-to_datetime()
입력 데이터의 형식을 추론하고, 유효성을 검사. 이를 올바른 형식의 데이터로 변환
잘못된 날짜 형식이나 값이 입력되면, 에러가 발생하지 않고 NaN 또는 NaT (Not a Time) 값을 반환.
3. 반환 값
-Timestamp()
입력 데이터의 형식에 따라 단일의 Timestamp 객체를 반환
-to_datetime()
입력 데이터에 따라 단일의 Timestamp 객체 또는 DatetimeIndex 객체를 반환
날짜와 시간 데이터 여러 개가 입력되면,
DatetimeIndex 객체는 해당 데이터들을 포함하는 인덱스로 사용됨
'''
# Timestamp()로 데이터 생성
tsT = pd.Timestamp('2022-01-01 12:34:56')
# to_datetime()로 데이터 생성
date_str = ['2022-01-01', '2022-01-02', '2022-01-03']
dates = pd.to_datetime(date_str)
print(tsT)
print(dates)
시계열 제어 - 날짜와 시간(DatatimeIndex)
# pd.DatetimeIndex()
# 날짜와 시간 데이터를 인덱스로 사용하기 위한 특수 데이터 구조
# 시계열 데이터를 쉽게 조작하고 분석하도록 도와줌
# 요약 : 날짜형 인덱스
import pandas as pd
# 날짜 문자열을 DatetimeIndex로 변환
data_list = ['2023-12-01', '2023-12-02', '2023-12-03', '2023-12-04']
index = pd.DatetimeIndex(data_list)
# 미리보기 : 12월 한번에 DatetimeIndex만들기
start_date = '2023-12-01'
end_date = '2023-12-31'
index = pd.date_range(start_date, end_date, freq='D')
# 12월 1주일 간격으로 날짜 생성 - 일요일
pd.date_range(start_date, end_date, freq='W-SUN')
# 날짜 데이터가 부족할 때
pd.to_datetime('2000')
pd.to_datetime('2000/03')
pd.to_datetime('10/03') #error
pd.to_datetime('12:34')
pd.to_datetime(1702731342736680500)
# 날짜 데이터가 잘못 되었을 때, errors=
date_list = ['2000', '2001/13/02', '2022.02.03', '12:34', '20:21', 1702731342736680500]
pd.to_datetime(date_list) # error
'''
errors= : {'ignore', 'raise', 'coerce'}, default 'raise'
raise
-잘못된 형식의 데이터가 있을 경우 ValueError를 발생
ignore(무시)
-잘못된 형식의 데이터를 무시하고 변환 시도
-변환할 수 없는 데이터는 그대로 유지
coerce(강제)
-잘못된 형식의 데이터를 NaT (Not a Time)로 대체
-NaT는 누락된 날짜/시간 값을 나타내는 특수한 Datetime 객체
-변환할 수 없는 데이터는 NaT로 대체되므로, 모든 값을 Datetime 객체로 변환할 수 있다.
'''
date_list = ['2000', '2001/13/02', '2022.02.03', '12:34', '20:21', 1702731342736680500]
pd.to_datetime(date_list,errors='coerce')
date_list = ['2000', '2001/13/02', '2022.02.03', '12:34', '20:21', 1702731342736680500]
pd.to_datetime(date_list,errors='ignore')
시계열 제어 - 날짜 범위 생성(date_range)
# pd.date_range()
# 날짜 범위를 생성하는 함수
# 시작일, 종료일, 날짜 간격
import pandas as pd
# 12월 한 번에 DatetimeIndex만들기
start_date = '2023-12-01'
end_date = '2023-12-31'
index = pd.date_range(start=start_date, end=end_date)
# 2023년 Day별로 DatetimeIndex만들기
pd.date_range('2023-01-01','2023.12.31')
# 특정 시간까지 포함하기
pd.date_range('2023-01-01 14:00:00','2023.12.31 23:59:59')
'''
Offset aliases
-다양한 시계열 빈도에 대해 유용한 문자열 별칭
-원하는 빈도에 맞게 데이터를 처리하고 분석
Period aliases
-다양한 일반적인 시계열 빈도에 대해 유용한 문자열 별칭
-원하는 빈도로 기간을 설정하고 분석하는 데 유용
Anchored offsets
-일부 빈도에서 앵커링 접미사를 지정할 수 있는 기능
-date_range, bdate_range, DatetimeIndex의 생성자 및
pandas의 다양한 시계열 관련 함수에서 인수로 사용
'''
# periods=
# 해당 기간을 10개 구간으로 만들기
pd.date_range('2023.01.01','2023.07.31', periods=10)
# freq=
# 12월 1주일 간격으로 날짜 생성 - 일요일
pd.date_range('2023.12.01','2023.12.31', freq='W')
# 2024년 매주 목요일 날짜 생성 - 목요일
pd.date_range('2024.01.01','2024.12.31', freq='W-THU')
# 2024년 달 간격으로 데이터를 만든다면?
pd.date_range('2024.01.01','2024.12.31', freq='M')
# 2024년 매달 1일 간격으로 데이터를 만든다면?
pd.date_range('2024.01.01','2024.12.31', freq='MS')
# 2024.01.01 ~12.31 10시간마다 간격으로 데이터를 만든다면?
pd.date_range('2024.01.01','2024.12.31', freq='10H')
# 인자 생략하기
# 2024.01부터 10개 만들기
pd.date_range('2024.01', periods=10, freq='BMS')
# 2024.01부터 월요일날 데이터 10개 만들기
pd.date_range('2024.01', periods=10, freq='W-MON')
# 2024.12.31을 마감으로 총 10개의 날짜 만들기
pd.date_range(end='2024.12.31', periods=10, freq='D')
# 2024.12.31을 마감으로 매주 화요일 총 10개의 날짜 만들기
pd.date_range(end='2024.12.31', periods=10, freq='W-TUE')
시계열 제어 - 기간과 기간 인덱스(Period, PeriodIndex, period_range, ,to_period, to_timestamp)
# 특정 시간(Timestamp) vs 기간(Period) vs 기간인덱스(PeriodIndex)
import pandas as pd
# Timestamp - 그 때 -> 몇시 몇분 몇초
pd.Timestamp('2024-12-31')
# Period - 그 날 -> 24시간
pd.Period('2024-12-31')
# Period + range = period_range() = PeriodIndex
# 사용 방법은 date_range()와 거의 같다.
pd.period_range('2024-01-01','2024-12-31')
pd.period_range('2024-01-01','2024-12-31', freq='M')
# 비교
pd.date_range('2024-01-01','2024-12-31', freq='M')
'''
PeriodIndex vs DatetimeIndex
-PeriodIndex : 기간 단위의 정보 vs DatetimeIndex : 날짜와 시간의 정밀한 정보
-dtype이 period[D], period[M] ... vs datetime64[ns]
PeriodIndex
-주어진 기간('2024-01', '2024-02', 등)을 나타내는 Period 객체의 배열로 구성
-각 원소는 해당 기간에 대한 정보
일반적으로 연, 월, 분기, 반기 등의 기간 단위를 표현하고 저장
-dtype은 'period[M]'으로 표시되며, M은 월 단위
'2024-01'은 2024년 1월을 나타내는 Period 객체
DatetimeIndex
-주어진 날짜('2024-01-31', '2024-02-29', 등)를 나타내는 Timestamp 객체의 배열로 구성
-각 원소는 해당 날짜와 시간에 대한 정보를 표현하고 저장
-dtype은 'datetime64[ns]'로 표시되며, ns는 나노초 단위의 정밀도를 나타냄
'2024-01-31'은 2024년 1월 31일을 나타내는 Timestamp 객체
'''
# PeriodIndex <-> DatetimeIndex 변환
# to_period() : DatetimeIndex > PeriodIndex
# to_timestamp() : PeriodIndex > DatetimeIndex
# DatetimeIndex > PeriodIndex
pd.date_range('2024-01-01','2024-12-31').to_period()
# PeriodIndex > DatetimeIndex
pd.period_range('2024-01-01','2024-12-31').to_timestamp()
시계열 제어 - 간격과 간격 인덱스(Timedelta, TimedeltaIndex, to_timedelta, timedelta_range)
# Timedelta : 간격, 시간차이
import pandas as pd
time1 = pd.Timestamp('2023.01.01 14:00')
time2 = pd.Timestamp('2023.01.01 14:20')
interval = time2 - time1
# to_timedelta()
texts = [
"2d",
"2days",
"2 days"
]
for t in texts:
print(pd.to_timedelta(t))
pd.to_timedelta('2days' '2days' '2days') # 6 days
texts = [
"5W 4D 3H 2m 1S",
"2days 4hours",
["1D", "2D", "3D"]
]
for t in texts:
print(pd.to_timedelta(t))
# timedelta_range()
# 1일 경과 2일 경과... 같은 연산
pd.timedelta_range(start='1days', periods=10)
# 1시간 경과 2시간 경과... 같은 연산
pd.timedelta_range(start='0', periods=10, freq='h')
# 10시간 경과 20시간 경과... 같은 연산
pd.timedelta_range(start='0', periods=10, freq='10h')
# freq은 모르겠고, 1일~10일을 5영역으로 나누고 싶다면
pd.timedelta_range(start='1d', end='10d', periods=5)
# closed=
# freq은 모르겠고, 1일~10일을 5영역으로 나누고 싶다면 + 양끝점 포함
pd.timedelta_range(start='1d', end='10d', periods=5, closed=None)
# freq은 모르겠고, 1일~10일을 5영역으로 나누고 싶다면 + 종료점 포함
pd.timedelta_range(start='1d', end='10d', periods=5, closed='right')
# freq은 모르겠고, 1일~10일을 5영역으로 나누고 싶다면 + 시작점 포함
pd.timedelta_range(start='1d', end='10d', periods=5, closed='left')
시계열 제어 - 날짜/시간 속성 접근자(.dt)
# 날짜/시간 속성 접근자 .dt
# 시리즈에서 날짜와 시간과 관련된 속성에 접근할 때 사용되는 기능
# .str처럼 .dt.메소드, .dt.속성 으로 사용
import pandas as pd
dec = pd.date_range('2024.12.01', '2024.12.31', freq='W-MON')
# Series 화
pd.Series(dec)
# DataFrame화
pd.DataFrame(dec, columns=['Weeks'])
# 체인형으로 프로그래밍 하고 싶다면 .to_frame()
dec.to_frame(name='Weeks') # index가 dec로 되어 버림
# Series화 > .toFrame을 통한 DataFrame
pd.Series(dec).to_frame(name='Weeks')
# 시리즈화를 직접하진 않고, DataFrame에서 조회하면 시리즈일 것
# 때문에 pd.Series(dec).to_frame({name}) 형태를 기억하기
dec_df = pd.Series(dec).to_frame(name='Weeks')
# .dt를 통해 속성(Properties) 접근 객체 생성
dec_df['Weeks'].dt
# Python Datetime하듯 .day로 바로 접근하면 에러
dec_df['Weeks'].day
# 중간에 .dt 넣으면
dec_df['Weeks'].dt.day
dec_df['Weeks'].dt.year
dec_df['Weeks'].dt.month
dec_df['Weeks'].dt.day_name()
dec_df['Weeks'].dt.to_period()
dec_df['Weeks'].dt.strftime('%B %d, %Y, %r')
dec_df['Weeks'].dt.strftime('%Y년 %m월 %d일')
시계열 제어 - Timestamp와 DatetimeIndex의 메소드와 속성(+한국 locale 포맷)
'''
속성(Attributes)와 속성(Properties)
-일반적으로 동일의미로 사용. 그러나 일부 상황에서는 다르게 사용할 때가 있음
-Pandas는 일반적인 상황처럼 동일의미로 쓰고 있음
case 1. 속성(Properties) = 속성(Attributes) + 메소드(Methods)
case 1+a. 객체는 Properties, 값은 Attributes
-.속성이 Object면 Properties
-.속성이 값, 수치라면 Attributes
-.속성이 함수라면 Methods
case 2. Attributes != Properties
-Attributes : 객체의 특정한 데이터나 상태를 의미
DataFrame에서 values, dtype, ndim 같이 DataFrame의 값이나 데이터 타입, 차원 등을 설명
-Properties : 객체의 특정한 특성이나 특징을 표현
DataFrame에서 shape, columns, index 같이 DataFrame의 구조나 크기를 설명
'''
# Timestamp의 메소드(Methods)와 속성(Attributes)
import pandas as pd
start = '2024-01-01'
end = '2024-12-31'
date_index = pd.date_range(start,end,freq='M')
data = list(range(200, 1400, 100))
df = pd.DataFrame(data=data, index=date_index, columns=['Data'])
# DatetimeIndex = [Timestamp,...] 의 속성 접근
df.index
df.index[0].month_name() # 'January'
df.index[1].month_name() # 'February'
# 2024.2월 말일 -> 29일
df.index[1].days_in_month # 29
df.index[1].day_name() # 'Thursday'
# 월 0, ...목 3
df.index[1].day_of_week # 3
df.index[1].weekday() # 3
df.index[1].year # 2024
# 2024.01.31 (수)
df.index[0].week # 5
# 2024.12.31(화)는 2024년 마지막 주이면서 2025년의 첫번째 주
df.index[11].week # 1
# DatetimeIndex 활용 예제 - 월(Month) 열 추가
df['Month'] = df.index.month_name()
# DatetimeIndex 활용 예제 - 요일(day) 열 추가
df['Days'] = df.index.day_name()
# DatetimeIndex 활용 예제 - 요일(day) 열 추가 - 한국(korea)버전
df['Days'] = df.index.day_name('ko_KR.utf8')
시계열 제어 - 데이터 셋에서 시계열 데이터 처리(to_datetime, parse_dates=)
import pandas as pd
cols = ['date', 'open', 'high', 'low', 'close']
stocks = pd.read_csv('AAPL.csv', usecols=cols, index_col='date')
# index > DatetimeIndex : to_datetime()
# 현재 index의 dtype?
stocks.index # object
# 방법 1. index의 속성 변경 to_datetime()
stocks.index = pd.to_datetime(stocks.index)
# 방법 2.
stocks = pd.read_csv('AAPL.csv', usecols=cols, index_col='date',parse_dates=['date'])
# 복습 : 요일 열 추가
days = stocks.index.day_name(locale='ko_KR.utf8')
stocks.insert(0,'요일',days)
시계열 제어 - 날짜 포맷 정리
import pandas as pd
cols = ['date', 'open', 'high', 'low', 'close']
stocks = pd.read_csv('AAPL.csv', usecols=cols, parse_dates=['date'])
# 날짜 포맷 정리
stocks['date'].dt.strftime('%Y.%m.%d %H:%M:%S')
# 변경 형태 : 미국장 현지시간 09:30 ~ 16:00
new_dates = stocks['date'].dt.strftime('%Y.%m.%d 시작09:30')
# 새로 계산된 열을 index로
stocks.set_index(new_dates, inplace=True)
# 불필요해진 열 drop
stocks.drop(columns='date',inplace=True)
# 새로운 .csv로 저장
stocks.to_csv('AAPL_NEW.csv')
시계열 제어 - 잘못된 날짜 포맷 정리
import pandas as pd
stocks = pd.read_csv('APPL_NEW.csv')
# 날짜 포맷이 깨진 데이터 정리
# 시도 1 parse_dates=['date']
stocks = pd.read_csv('AAPL_NEW.csv', parse=dates=['date'])
stocks['date'].info() # object
# 시도 2 : to_datetime
pd.to_datetime(stocks['date']) #설정이 안됨
# 해결 - 현재 데이터를 인식할 포맷 입력
new_date = pd.to_datetime(stocks['date'], format='%Y.%m.%d 시작09:30:00')
# 기존 열 변경
stocks['date'] = new_date
시계열 제어 - 시계열의 조회(.loc)
import pandas as pd
cols = ['date', 'open', 'high', 'low', 'close']
stocks = pd.read_csv('AAPL.csv', usecols=cols, index_col='date', parse_dates=['date'])
# 연월일 .loc['label']
stocks.loc['2015-05-27']
# .loc[['label1', 'label2']]
stocks.loc[['2015-05-27','2015-06-01']]
# 슬라이싱 1
stocks.loc['2015-5-27':'2015-06-1']
# 슬라이싱 2
stocks.loc[:'2015-06-1']
# 연월만 탐색
stocks.loc['2015.05']
# 연월 슬라이싱
stocks.loc['2015.05':'2015.06']
# 연 조회
stocks.loc['2015']
시계열 제어 - 재색인(reindex)와 결측치 결정
# 재색인(reindex)
# 인덱스를 새로운 인덱스로 변경하거나 재정렬하는 작업
# 데이터를 새로운 인덱스에 맞게 재배열하거나 누락된 값을 처리하는 데 유용
# 시리즈, 데이터프레임 모두 가능
import pandas as pd
cols = ['date', 'open', 'high', 'low', 'close']
stocks = pd.read_csv('AAPL.csv', usecols=cols, index_col='date', parse_dates=['date'])
stocks.index.day_name().value_counts() # 현재 위 데이터에 없는 요일이 있다.
# 월화수목금+토일
# 1. 기간 찾기
# 가장 과거 날짜
min_date = stocks.index.min()
# 가장 최근 날짜
max_date = stocks.index.max()
# 2. 비어있는 날짜까지 데이터 생성
new_index = pd.date_range(start=min_date, end=max_date)
new_index.day_name().value_counts() # 생성
# 3.1 재색인(reindex) + 결측치 채우기('휴장')
# .fillna()로 채우거나, fill_value=로 채우거나
stocks.reindex(new_index).fillna('휴장')
stocks.reindex(new_index, fill_value='휴장')
# 3.2 재색인(reindex) + 결측치 채우기(이전일)
stocks.reindex(new_index).ffill()
stocks_new = stocks.reindex(new_index, method='ffill')
# 4. 요일 열 추가
days = stocks_new2.index.day_name(locale='ko_KR.utf8')
stocks_new.insert(0,'요일',days)
시계열 제어 - 재샘플링(resample)
# 재샘플링(resample)
# 시계열 데이터의 주기를 변경하는 작업
# 다운 샘플링 : 데이터 빈도(frequency)를 더 낮은 주기로 설정
# 업 샘플링 : 데이터 빈도를 더 높은 주기로 업샘플링
'''
1. 다운샘플링 간단 예제
-주어진 데이터의 빈도를 낮추는 작업
-데이터가 일별로 주어졌을 때 주간, 월간 등 더 낮은 주기로 데이터를 집계
-다운샘플링할 주기를 나타내는 문자열 또는 오프셋 문자열을 인자로 전달
-다운샘플링 시에는 집계(aggregation) 함수를 사용하여 데이터를 요약
'''
import pandas as pd
# 데이터 생성
data = {'value': [10, 20, 30, 40, 50]}
index = pd.date_range('2021-01-01', periods=5, freq='D')
df = pd.DataFrame(data, index=index)
# 주간 평균으로 다운샘플링
weekly_df = df.resample('W').mean()
'''
2. 업샘플링 간단 예제
-주어진 데이터의 빈도를 높이는 작업
-데이터가 월별로 주어졌을 때 일별, 시간별 등 더 높은 주기로 데이터를 채움
-업샘플링할 주기를 나타내는 문자열 또는 오프셋 문자열을 인자로 전달
-업샘플링 시에는 보간(interpolation)을 통해 데이터를 채움
-보간 방식을 method= 로 정해줘야함
'''
# 원본 데이터 생성
data = {'value': [10, 20]}
index = pd.to_datetime(['2021-01-01', '2021-02-01'])
df = pd.DataFrame(data, index=index)
# 일별로 업샘플링하고 선형 보간으로 데이터 채우기
weekly_df = df.resample('D').asfreq().interpolate()
'''
보간(Interpolation)
-주어진 데이터 사이에 누락값을 추정하는 방법
-선형 보간, 최근접 이웃 보간, 다항식 보간 등
.asfreq()
-업샘플링 시에 사용되는 함수
-주어진 주기에 맞게 데이터를 새로운 인덱스로 재구성
-누락된 데이터를 NaN 값으로 채움
.interpolate()
-업샘플링 시에 사용되는 함수로, 보간을 수행하여 누락된 값을 추정
-method 매개변수를 사용하여 다른 보간 방법을 선택
'''
# 본 데이터 실습 - 다운샘플링
import pandas as pd
cols = ['date', 'open', 'high', 'low', 'close']
stocks = pd.read_csv('AAPL.csv', usecols=cols, index_col='date', parse_dates=['date'])
# 1. 연 단위로 resample (= groupby 데이터 유사)
stocks_years = stocks.resample('AS')
# 다운 샘플링 데이터는 groupby 처럼 다룰 수 있다.
stocks_years.groups # 우측의 숫자는 경계선에 있는 데이터의 인덱스 위치
# 다운 샘플링 데이터는 groupby 처럼 다룰 수 있다. + 시계열 장점인 '2020-01-01'는 안됨
stocks_years.get_group('2017-01-01 00:00:00+0000')
# 2. 다운샘플링 이후 집계함수
# 집계함수 mean으로 년도별 평균 구하기
stocks_years.mean(2).round(2)
# agg()로 집계함수 max, min, mean 년도별 결과 구하기
stocks_years.agg(['max','min','mean'])
# 데이터프레임 인덱스를 period로
# 'AS'로 하면 : ValueError: Invalid frequency: <YearBegin: month=1>
stocks_years = stocks.resample('A',kind='period')
# 월 단위로 집계 결과 보기
stocks_month = stocks.resample('M',kind='period')
# 월 단위로 .agg() 결과 보기 1
stocks_month.agg(['max','min','mean'])
# 월 단위로 .agg() 결과 보기 2
stocks_month.agg({'high':['max','min'],'low':['max','min']})'TIL' 카테고리의 다른 글
| 데이터 분석 과정 학습 및 시각화 실습(2) (2) | 2024.01.09 |
|---|---|
| 데이터 분석 과정 학습 및 시각화 실습(1) (2) | 2024.01.08 |
| Python 프로그래밍 및 Pandas 활용 실습(5)-1 (1) | 2024.01.06 |
| Python 프로그래밍 및 Pandas 활용 실습(4) (1) | 2024.01.05 |
| Python 프로그래밍 및 Pandas 활용 실습(3)-2 (0) | 2024.01.04 |