5 분 소요

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

시계열 데이터(Time Series Data)

  1. 100일간의 시계열 데이터를 생성하고 이를 선 그래프로 시각화하는 코드를 작성하세요.
np.random.seed(42)
date_range = pd.date_range(start="2023-01-01", periods=100, freq="D")
values = np.cumsum(np.random.randn(100))
plt.figure(figsize=(9, 6))
plt.plot(date_range, values)
plt.xlabel("Date")
plt.ylabel("Value")
plt.show()

png

  1. 1번에서 생성한 데이터를 기반으로 7일 이동 평균을 계산하고 원본 데이터와 함께 그래프로 비교하는 코드를 작성하세요.
np.random.seed(42)
date_range = pd.date_range(start="2023-01-01", periods=100, freq="D")
values = np.cumsum(np.random.randn(100))
plt.figure(figsize=(9, 6))

values_series = pd.Series(values, index=date_range)
rolling = values_series.rolling(window=7).mean()
plt.plot(date_range, values, label="Original Data")
plt.plot(date_range, rolling, label="Moving Data")

plt.xlabel("Date")
plt.ylabel("Value")
plt.legend()
plt.show()

png

  1. 1번에서 생성한 시계열 데이터에서 이상치를 탐지하고 이상치만 강조하여 그래프에 표시하는 코드를 작성하세요. 이상치는 사분위수 범위(IQR)를 이용해 판단합니다.
np.random.seed(42)
date_range = pd.date_range(start="2023-01-01", periods=100, freq="D")
values = np.cumsum(np.random.randn(100))
plt.figure(figsize=(9, 6))
plt.plot(date_range, values)

Q1 = np.percentile(values, 25)
Q3 = np.percentile(values, 75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR

outliers = values[(values < lower_bound) | (values > upper_bound)]
outliers_dates = date_range[(values < lower_bound) | (values > upper_bound)]

plt.scatter(outliers_dates, outliers, s = 100, color="red", marker = 'o', label="Outliers")
plt.xlabel("Date")
plt.ylabel("Value")
plt.legend()
plt.show()

png

리샘플링(Resampling)

  1. Pandas를 사용하여 3시간 간격의 시계열 데이터를 생성한 후 하루 단위(D)로 평균을 구하는 다운 샘플링을 수행하는 코드를 작성하세요.
date_rng = pd.date_range(start="2024-01-01", end="2024-01-05", freq="3h")
df = pd.DataFrame({
    "datetime": date_rng,
    "value": np.random.randn(len(date_rng))
})

df = df.set_index("datetime")
df_d = df.resample("D").mean()
df_d
value
datetime
2024-01-01 -0.084685
2024-01-02 0.108810
2024-01-03 0.071744
2024-01-04 -0.083181
2024-01-05 -1.062304
  1. 3시간 간격으로 생성된 시계열 데이터에서 1시간 단위로 업 샘플링한 후 선형보간(linear)을 적용하는 코드를 작성하세요.
date_rng = pd.date_range(start="2024-01-01", end="2024-01-03", freq="3h")
df = pd.DataFrame({
    "datetime": date_rng,
    "value": np.random.randn(len(date_rng))
})

df = df.set_index("datetime")
df_h = df.resample("H").interpolate(method="linear")
df_h.head()
<ipython-input-30-93838bc24f67>:7: FutureWarning: 'H' is deprecated and will be removed in a future version, please use 'h' instead.
  df_h = df.resample("H").interpolate(method="linear")
value
datetime
2024-01-01 00:00:00 0.250493
2024-01-01 01:00:00 0.282478
2024-01-01 02:00:00 0.314463
2024-01-01 03:00:00 0.346448
2024-01-01 04:00:00 0.004291
  1. 3시간 간격으로 생성된 시계열 데이터에서 하루 단위(D)로 다운 샘플링을 수행한 후 각 날짜에 해당하는 최소(min)값과 최대(max)값을 출력하는 코드를 작성하세요.
date_rng = pd.date_range(start="2024-01-01", end="2024-01-07", freq="3h")
df = pd.DataFrame({
    "datetime": date_rng,
    "value": np.random.randn(len(date_rng))
})

df = df.set_index("datetime")
df_d = df.resample("D").agg(["min", "max"])
df_d
value
min max
datetime
2024-01-01 -1.792045 1.912318
2024-01-02 -2.090018 1.770432
2024-01-03 -0.477382 1.357881
2024-01-04 -2.037076 1.570032
2024-01-05 -1.445610 1.271138
2024-01-06 -0.431942 2.275761
2024-01-07 1.200412 1.200412

이동평균(Moving Average)

  1. 주어진 시계열 데이터에서 7일 단순 이동평균(SMA)을 계산하여 새로운 컬럼을 추가하는 코드를 작성하세요.
date_rng = pd.date_range(start="2024-01-01", end="2024-01-20", freq="D")
df = pd.DataFrame({
    "datetime": date_rng,
    "value": np.random.randint(50, 150, size=len(date_rng))
})
df = df.set_index("datetime")
df['SMA'] = df['value'].rolling(window=7).mean()
df
value SMA
datetime
2024-01-01 64 NaN
2024-01-02 103 NaN
2024-01-03 109 NaN
2024-01-04 146 NaN
2024-01-05 57 NaN
2024-01-06 102 NaN
2024-01-07 109 98.571429
2024-01-08 54 97.142857
2024-01-09 117 99.142857
2024-01-10 55 91.428571
2024-01-11 145 91.285714
2024-01-12 143 103.571429
2024-01-13 96 102.714286
2024-01-14 148 108.285714
2024-01-15 104 115.428571
2024-01-16 89 111.428571
2024-01-17 101 118.000000
2024-01-18 65 106.571429
2024-01-19 62 95.000000
2024-01-20 79 92.571429
  1. 시계열 데이터에서 7일 지수 이동평균(EMA)을 계산하고 기존 데이터와 비교하여 출력하는 코드를 작성하세요.
date_rng = pd.date_range(start="2024-01-01", end="2024-01-20", freq="D")
df = pd.DataFrame({
    "datetime": date_rng,
    "value": np.random.randint(50, 150, size=len(date_rng))
})
df = df.set_index("datetime")
df['EMA'] = df['value'].ewm(span=7).mean()
df
value EMA
datetime
2024-01-01 68 68.000000
2024-01-02 66 66.857143
2024-01-03 112 86.378378
2024-01-04 68 79.657143
2024-01-05 141 99.764405
2024-01-06 107 101.964954
2024-01-07 104 102.552088
2024-01-08 139 112.677779
2024-01-09 139 119.792544
2024-01-10 111 117.463236
2024-01-11 72 105.596222
2024-01-12 58 93.307918
2024-01-13 61 85.034382
2024-01-14 50 76.116895
2024-01-15 107 83.942245
2024-01-16 50 75.370775
2024-01-17 83 77.292527
2024-01-18 145 94.315365
2024-01-19 97 94.989374
2024-01-20 138 105.776238
  1. 주어진 시계열 데이터에서 이동평균을 활용하여 변동성이 큰 날을 탐색하는 코드를 작성하세요. 7일 단순 이동평균(SMA)과 비교하여 특정 일자의 값이 이동평균보다 $\pm$ 20% 이상 차이가 나는 경우만 출력하세요.
date_rng = pd.date_range(start="2024-01-01", end="2024-01-20", freq="D")
df = pd.DataFrame({
    "datetime": date_rng,
    "value": np.random.randint(50, 150, size=len(date_rng))
})
df = df.set_index("datetime")
df['SMA'] = df['value'].rolling(window=7).mean()

result = df[(df['value'] - df['SMA']).abs() > 0.2 * df['SMA']]
result
value SMA
datetime
2024-01-07 71 91.285714
2024-01-08 142 104.428571
2024-01-11 75 108.428571
2024-01-12 65 101.714286
2024-01-14 135 108.285714
2024-01-16 78 97.714286
2024-01-17 127 98.000000
2024-01-18 141 107.428571

금융 데이터(Financial Data)

  1. 샘플 금융 데이터프레임을 직접 생성한 후 데이터의 기분 정보(행 개수, 열 개수, 데이터 타입 등)를 출력하는 코드를 작성하세요.
data = {
    'Date': pd.date_range(start='2024-01-01', periods=10, freq='D'),
    'Open': [100, 102, 105, 103, 108, 107, 110, 112, 115, 118],
    'High': [102, 106, 108, 107, 110, 109, 112, 115, 117, 120],
    'Low': [98, 100, 103, 101, 106, 105, 108, 110, 113, 116],
    'Close': [101, 104, 106, 105, 109, 108, 111, 113, 116, 119],
    'Volume': [1000, 1200, 1500, 1300, 1600, 1400, 1700, 1800, 1900, 2000]
}
df = pd.DataFrame(data)
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 10 entries, 0 to 9
Data columns (total 6 columns):
 #   Column  Non-Null Count  Dtype         
---  ------  --------------  -----         
 0   Date    10 non-null     datetime64[ns]
 1   Open    10 non-null     int64         
 2   High    10 non-null     int64         
 3   Low     10 non-null     int64         
 4   Close   10 non-null     int64         
 5   Volume  10 non-null     int64         
dtypes: datetime64[ns](1), int64(5)
memory usage: 612.0 bytes
  1. 주어진 df 데이터프레임에서 5일 이동평균(SMA)과 5일 지수 이동평균(EMA)을 계산하는 코드를 작성하세요.
data = {
    'Date': pd.date_range(start='2024-01-01', periods=10, freq='D'),
    'Close': [101, 104, 106, 105, 109, 108, 111, 113, 116, 119]
}
df = pd.DataFrame(data)
df['SMA'] = df['Close'].rolling(window=5).mean()
df['EMA'] = df['Close'].ewm(span=5).mean()
df
Date Close SMA EMA
0 2024-01-01 101 NaN 101.000000
1 2024-01-02 104 NaN 102.800000
2 2024-01-03 106 NaN 104.315789
3 2024-01-04 105 NaN 104.600000
4 2024-01-05 109 105.0 106.289100
5 2024-01-06 108 106.4 106.914286
6 2024-01-07 111 107.8 108.360855
7 2024-01-08 113 109.2 109.970024
8 2024-01-09 116 111.4 112.033697
9 2024-01-10 119 113.4 114.396777
  1. df 데이터프레임에서 주간(7일) 단위로 종가(Close) 평균을 리샘플링 한 후 이를 바탕으로 주간 변동성(표준편차)을 계산하는 코드를 작성하세요.
date_rng = pd.date_range(start='2024-01-01', periods=30, freq='D')
close_prices = np.random.uniform(100, 200, size=len(date_rng))
df = pd.DataFrame({
    'Date': date_rng,
    'Close': close_prices
})

df = df.set_index('Date')

weekly_df = df.resample('W').agg(Weekly_std=('Close', 'std'))

weekly_df
Weekly_std
Date
2024-01-07 29.527025
2024-01-14 21.552952
2024-01-21 28.471306
2024-01-28 27.804352
2024-02-04 27.990682