การวิเคราะห์ข้อมูลอนุกรมเวลา (Time Series) เป็นหนึ่งในจุดแข็งที่สำคัญของ Pandas โดยเฉพาะในการทำงานกับข้อมูลทางการเงิน ข้อมูลเซ็นเซอร์ ข้อมูลสภาพอากาศ หรือข้อมูลที่มีการบันทึกตามช่วงเวลา Pandas มี ฟังก์ชันพิเศษ (Built-in Functions) ที่ออกแบบมาโดยเฉพาะเพื่อจัดการกับวันที่และเวลาอย่างมีประสิทธิภาพ
%%{init: {'theme':'base', 'themeVariables': { 'primaryColor':'#b8bb26','primaryTextColor':'#282828','primaryBorderColor':'#fabd2f','lineColor':'#83a598','secondaryColor':'#d3869b','tertiaryColor':'#8ec07c','background':'#282828','mainBkg':'#3c3836','textColor':'#ebdbb2'}}}%%
graph TB
A["การจัดการข้อมูลอนุกรมเวลา
(Time Series Management)"]
A --> B["การแปลงข้อมูล
(Data Conversion)"]
A --> C["การจัดการดัชนี
(Index Management)"]
A --> D["การสุ่มตัวอย่าง
(Resampling)"]
A --> E["การคำนวณเคลื่อนที่
(Rolling Calculations)"]
B --> B1["pd.to_datetime()"]
B --> B2["DateOffset"]
C --> C1["set_index()"]
C --> C2["Date Range"]
D --> D1["Upsampling"]
D --> D2["Downsampling"]
E --> E1["Rolling Mean"]
E --> E2["Expanding"]
style A fill:#458588,stroke:#ebdbb2,color:#ebdbb2
style B fill:#689d6a,stroke:#ebdbb2,color:#282828
style C fill:#689d6a,stroke:#ebdbb2,color:#282828
style D fill:#689d6a,stroke:#ebdbb2,color:#282828
style E fill:#689d6a,stroke:#ebdbb2,color:#282828
ข้อมูลวันที่และเวลามักจะถูกเก็บในรูปแบบของ String (ข้อความ) เช่น "2024-01-15" หรือ "15/01/2024" ซึ่งไม่สามารถใช้ในการคำนวณทางคณิตศาสตร์ได้ Pandas จึงมีฟังก์ชัน pd.to_datetime() ที่ช่วยแปลงข้อความเหล่านี้ให้เป็น Datetime Object ที่สามารถคำนวณและจัดการได้
import pandas as pd
import numpy as np
def convert_to_datetime_basic():
"""
แสดงวิธีการแปลงข้อมูลแบบต่างๆ ให้เป็น Datetime
Returns:
DataFrame: ตารางแสดงข้อมูลก่อนและหลังการแปลง
"""
# สร้างข้อมูลตัวอย่าง
data = {
'date_str': ['2024-01-15', '2024-02-20', '2024-03-10'],
'date_thai': ['15/01/2024', '20/02/2024', '10/03/2024'],
'timestamp': [1705276800, 1708387200, 1710028800]
}
df = pd.DataFrame(data)
# แปลงรูปแบบ ISO (YYYY-MM-DD)
df['datetime_iso'] = pd.to_datetime(df['date_str'])
# แปลงรูปแบบ DD/MM/YYYY ต้องระบุ format
df['datetime_thai'] = pd.to_datetime(df['date_thai'], format='%d/%m/%Y')
# แปลงจาก Unix timestamp (วินาที)
df['datetime_unix'] = pd.to_datetime(df['timestamp'], unit='s')
return df
# ตัวอย่างการใช้งาน
result = convert_to_datetime_basic()
print(result)
print(f"\nชนิดข้อมูลของ datetime_iso: {result['datetime_iso'].dtype}")
ผลลัพธ์:
date_str date_thai timestamp datetime_iso datetime_thai datetime_unix
0 2024-01-15 15/01/2024 1705276800 2024-01-15 2024-01-15 2024-01-15 00:00:00
1 2024-02-20 20/02/2024 1708387200 2024-02-20 2024-02-20 2024-02-20 00:00:00
2 2024-03-10 10/03/2024 1710028800 2024-03-10 2024-03-10 2024-03-10 00:00:00
ชนิดข้อมูลของ datetime_iso: datetime64[ns]
| Format Code | ความหมาย | ตัวอย่าง |
|---|---|---|
%Y |
ปี 4 หลัก | 2024 |
%y |
ปี 2 หลัก | 24 |
%m |
เดือนเป็นตัวเลข | 01, 12 |
%B |
ชื่อเดือนเต็ม | January |
%b |
ชื่อเดือนย่อ | Jan |
%d |
วันที่ | 01, 31 |
%H |
ชั่วโมง (24 ชม.) | 00-23 |
%M |
นาที | 00-59 |
%S |
วินาที | 00-59 |
def handle_datetime_errors():
"""
แสดงวิธีจัดการกับข้อมูลวันที่ที่มีปัญหา
Returns:
DataFrame: ข้อมูลที่ผ่านการจัดการข้อผิดพลาด
"""
# ข้อมูลที่มีปัญหาปะปน
problematic_dates = ['2024-01-15', 'invalid_date', '2024-02-30', '2024-03-10']
# errors='coerce' จะแปลงค่าที่ผิดเป็น NaT (Not a Time)
dates_coerce = pd.to_datetime(problematic_dates, errors='coerce')
# errors='ignore' จะคงค่าเดิมไว้หากแปลงไม่ได้
dates_ignore = pd.to_datetime(problematic_dates, errors='ignore')
df = pd.DataFrame({
'original': problematic_dates,
'coerce': dates_coerce,
'ignore': dates_ignore
})
return df
# ตัวอย่างการใช้งาน
result = handle_datetime_errors()
print(result)
def extract_date_components():
"""
แสดงวิธีดึงส่วนประกอบต่างๆ ของวันที่
Returns:
DataFrame: ตารางแสดงส่วนประกอบต่างๆ
"""
# สร้างข้อมูลตัวอย่าง
dates = pd.date_range('2024-01-01', periods=5, freq='D')
df = pd.DataFrame({'date': dates})
# ดึงส่วนประกอบต่างๆ
df['year'] = df['date'].dt.year # ปี
df['month'] = df['date'].dt.month # เดือน
df['day'] = df['date'].dt.day # วันที่
df['dayofweek'] = df['date'].dt.dayofweek # วันในสัปดาห์ (0=จันทร์)
df['day_name'] = df['date'].dt.day_name() # ชื่อวัน
df['quarter'] = df['date'].dt.quarter # ไตรมาส
df['is_month_end'] = df['date'].dt.is_month_end # เป็นวันสุดท้ายของเดือนหรือไม่
return df
# ตัวอย่างการใช้งาน
result = extract_date_components()
print(result)
การตั้งค่าคอลัมน์วันที่เป็น Index ของ DataFrame จะทำให้การทำงานกับข้อมูลอนุกรมเวลามีประสิทธิภาพมากขึ้น โดยเฉพาะการกรองข้อมูลตามช่วงเวลา การ Plot กราฟ และการ Resample
def create_datetime_index():
"""
แสดงวิธีสร้างและใช้งาน DatetimeIndex
Returns:
DataFrame: DataFrame ที่มี DatetimeIndex
"""
# วิธีที่ 1: ใช้ pd.date_range()
dates = pd.date_range(start='2024-01-01', end='2024-01-10', freq='D')
# สร้าง DataFrame พร้อม Index เป็นวันที่
df = pd.DataFrame({
'sales': np.random.randint(100, 1000, size=10),
'customers': np.random.randint(10, 100, size=10)
}, index=dates)
print("DataFrame with DatetimeIndex:")
print(df.head())
print(f"\nIndex Type: {type(df.index)}")
return df
# ตัวอย่างการใช้งาน
df = create_datetime_index()
def convert_column_to_index():
"""
แสดงวิธีแปลง Column วันที่ให้เป็น Index
Returns:
DataFrame: DataFrame ที่แปลง Column เป็น Index แล้ว
"""
# สร้างข้อมูลที่มี Column วันที่
data = {
'date': pd.date_range('2024-01-01', periods=10, freq='D'),
'temperature': np.random.uniform(20, 35, 10).round(1),
'humidity': np.random.uniform(40, 90, 10).round(1)
}
df = pd.DataFrame(data)
print("Before setting index:")
print(df.head())
# แปลง Column 'date' เป็น Index
df = df.set_index('date')
print("\nAfter setting index:")
print(df.head())
return df
# ตัวอย่างการใช้งาน
df = convert_column_to_index()
%%{init: {'theme':'base', 'themeVariables': { 'primaryColor':'#b8bb26','primaryTextColor':'#282828','primaryBorderColor':'#fabd2f','lineColor':'#83a598','secondaryColor':'#d3869b','tertiaryColor':'#8ec07c','background':'#282828','mainBkg':'#3c3836','textColor':'#ebdbb2'}}}%%
graph LR
A["DataFrame
ทั้งหมด"] --> B["การกรองด้วย
Slice Notation"]
A --> C["การกรองด้วย
loc[]"]
A --> D["การกรองด้วย
Boolean Mask"]
B --> B1["df['2024-01']
ทั้งเดือน"]
B --> B2["df['2024-01-01':'2024-01-15']
ช่วงวันที่"]
C --> C1["df.loc['2024-01-01']
วันเดียว"]
D --> D1["df[df.index.month == 1]
เงื่อนไขซับซ้อน"]
style A fill:#458588,stroke:#ebdbb2,color:#ebdbb2
style B fill:#b8bb26,stroke:#282828,color:#282828
style C fill:#b8bb26,stroke:#282828,color:#282828
style D fill:#b8bb26,stroke:#282828,color:#282828
def filter_by_date_range():
"""
แสดงวิธีกรองข้อมูลด้วยช่วงวันที่ต่างๆ
Returns:
dict: Dictionary ที่เก็บผลลัพธ์การกรองแต่ละแบบ
"""
# สร้างข้อมูลตัวอย่าง
dates = pd.date_range('2024-01-01', periods=60, freq='D')
df = pd.DataFrame({
'value': np.random.randn(60).cumsum()
}, index=dates)
results = {}
# วิธีที่ 1: กรองทั้งเดือน
results['january'] = df['2024-01']
# วิธีที่ 2: กรองช่วงวันที่เฉพาะ
results['mid_month'] = df['2024-01-10':'2024-01-20']
# วิธีที่ 3: ใช้ loc[] สำหรับวันเดียว
results['specific_day'] = df.loc['2024-01-15']
# วิธีที่ 4: กรองด้วยเงื่อนไขซับซ้อน (วันจันทร์ทั้งหมด)
results['mondays'] = df[df.index.dayofweek == 0]
# วิธีที่ 5: กรองสัปดาห์ที่ 3 ของทุกเดือน
results['week_3'] = df[df.index.day.isin(range(15, 22))]
return results, df
# ตัวอย่างการใช้งาน
results, original_df = filter_by_date_range()
print("Original DataFrame shape:", original_df.shape)
print("\nJanuary data shape:", results['january'].shape)
print("\nMid-month data:")
print(results['mid_month'].head())
| Frequency | ความหมาย | ตัวอย่าง |
|---|---|---|
D |
รายวัน (Day) | freq='D' |
W |
รายสัปดาห์ (Week) | freq='W' |
M |
วันสุดท้ายของเดือน (Month End) | freq='M' |
MS |
วันแรกของเดือน (Month Start) | freq='MS' |
Q |
วันสุดท้ายของไตรมาส (Quarter End) | freq='Q' |
Y |
วันสุดท้ายของปี (Year End) | freq='Y' |
H |
รายชั่วโมง (Hour) | freq='H' |
T หรือ min |
รายนาที (Minute) | freq='T' |
S |
รายวินาที (Second) | freq='S' |
B |
วันทำการ (Business Day) | freq='B' |
Resampling คือการเปลี่ยนความถี่ของข้อมูลอนุกรมเวลา แบ่งออกเป็น 2 ประเภทหลัก:
การรวมข้อมูลความถี่สูงเป็นความถี่ต่ำต้องใช้ ฟังก์ชันการรวบรวม (Aggregation Function) เช่น sum, mean, max, min
โดยที่:
def demonstrate_downsampling():
"""
แสดงวิธีทำ Downsampling ด้วยฟังก์ชันต่างๆ
Returns:
dict: Dictionary ที่เก็บผลลัพธ์การ Resample แต่ละแบบ
"""
# สร้างข้อมูลรายชั่วโมง
dates = pd.date_range('2024-01-01', periods=24*7, freq='H') # 1 สัปดาห์
df = pd.DataFrame({
'temperature': np.random.uniform(15, 30, len(dates)),
'sales': np.random.randint(0, 100, len(dates)),
'visitors': np.random.randint(10, 200, len(dates))
}, index=dates)
results = {}
# Resample เป็นรายวัน - ใช้ค่าเฉลี่ย
results['daily_mean'] = df.resample('D').mean()
# Resample เป็นรายวัน - ใช้ผลรวม
results['daily_sum'] = df.resample('D').sum()
# Resample เป็นรายวัน - ใช้หลายฟังก์ชันพร้อมกัน
results['daily_agg'] = df.resample('D').agg({
'temperature': ['mean', 'max', 'min'],
'sales': 'sum',
'visitors': 'sum'
})
# Resample เป็นราย 6 ชั่วโมง
results['6h'] = df.resample('6H').mean()
# Resample เป็นรายสัปดาห์
results['weekly'] = df.resample('W').agg({
'temperature': 'mean',
'sales': 'sum',
'visitors': 'sum'
})
print("Original data shape:", df.shape)
print("\nDaily mean shape:", results['daily_mean'].shape)
print("\nDaily aggregation:")
print(results['daily_agg'].head())
return results, df
# ตัวอย่างการใช้งาน
results, original_df = demonstrate_downsampling()
การเพิ่มความถี่ข้อมูลจะทำให้เกิด ช่องว่าง (Missing Values) ที่ต้องจัดการด้วยวิธีการต่างๆ เช่น Forward Fill, Backward Fill, หรือ Interpolation
def demonstrate_upsampling():
"""
แสดงวิธีทำ Upsampling และการจัดการค่าว่าง
Returns:
DataFrame: DataFrame ที่ Upsample แล้ว
"""
# สร้างข้อมูลรายวัน
dates = pd.date_range('2024-01-01', periods=7, freq='D')
df = pd.DataFrame({
'price': [100, 105, 103, 108, 106, 110, 112]
}, index=dates)
print("Original daily data:")
print(df)
# Upsample เป็นรายชั่วโมง
hourly = df.resample('H').asfreq()
print("\n\nAfter upsampling to hourly (with NaN):")
print(hourly.head(25))
# จัดการค่าว่างด้วย Forward Fill
hourly_ffill = df.resample('H').ffill()
print("\n\nWith Forward Fill:")
print(hourly_ffill.head(25))
# จัดการค่าว่างด้วย Interpolation (Linear)
hourly_interpolate = df.resample('H').interpolate(method='linear')
print("\n\nWith Linear Interpolation:")
print(hourly_interpolate.head(25))
return hourly_ffill, hourly_interpolate
# ตัวอย่างการใช้งาน
ffill_df, interp_df = demonstrate_upsampling()
| Method | ความหมาย | เหมาะกับ |
|---|---|---|
ffill() |
Forward Fill - ใช้ค่าก่อนหน้าไปเติม | ราคาหุ้น, สถานะ On/Off |
bfill() |
Backward Fill - ใช้ค่าถัดไปมาเติม | การพยากรณ์ย้อนหลัง |
interpolate() |
คำนวณค่ากลางระหว่างจุด | อุณหภูมิ, ข้อมูลต่อเนื่อง |
fillna(value) |
เติมด้วยค่าคงที่ | ใช้ค่าเฉลี่ยหรือ 0 |
def advanced_resampling():
"""
แสดงเทคนิค Resample ขั้นสูง
Returns:
dict: ผลลัพธ์การ Resample แบบต่างๆ
"""
# สร้างข้อมูล Intraday (ภายในวัน)
dates = pd.date_range('2024-01-01 09:00', periods=390, freq='T') # ทุก 1 นาที
df = pd.DataFrame({
'stock_price': 100 + np.random.randn(390).cumsum() * 0.1
}, index=dates)
results = {}
# Resample ทุก 5 นาที - แบบ OHLC (Open, High, Low, Close)
results['5min_ohlc'] = df.resample('5T').ohlc()
# Resample ทุก 15 นาที - คำนวณหลายค่า
results['15min'] = df.resample('15T').agg({
'stock_price': ['first', 'last', 'max', 'min', 'mean']
})
# Resample ทุก 30 นาที - เริ่มที่นาทีที่ 15
results['30min_offset'] = df.resample('30T', offset='15T').mean()
# Resample รายชั่วโมง - ใช้ label='right' (แสดงเวลาสิ้นสุด)
results['hourly_right'] = df.resample('H', label='right').mean()
print("5-minute OHLC:")
print(results['5min_ohlc'].head())
return results, df
# ตัวอย่างการใช้งาน
results, stock_df = advanced_resampling()
Rolling Window เป็นเทคนิคที่ใช้คำนวณค่าสถิติจากกลุ่มข้อมูลที่เลื่อนไปเรื่อยๆ (Sliding Window) มักใช้ในการหา Moving Average, Volatility, และตัวชี้วัดทางเทคนิคต่างๆ
โดยที่:
%%{init: {'theme':'base', 'themeVariables': { 'primaryColor':'#b8bb26','primaryTextColor':'#282828','primaryBorderColor':'#fabd2f','lineColor':'#83a598','secondaryColor':'#d3869b','tertiaryColor':'#8ec07c','background':'#282828','mainBkg':'#3c3836','textColor':'#ebdbb2'}}}%%
sequenceDiagram
participant D as Data Points
participant W1 as Window 1
participant W2 as Window 2
participant W3 as Window 3
participant R as Result
D->>W1: [1, 2, 3, 4, 5]
First 5 points
W1->>R: Mean = 3.0
D->>W2: [2, 3, 4, 5, 6]
Slide +1
W2->>R: Mean = 4.0
D->>W3: [3, 4, 5, 6, 7]
Slide +1
W3->>R: Mean = 5.0
Note over D,R: Rolling window size = 5
def basic_rolling_calculations():
"""
แสดงการคำนวณแบบ Rolling พื้นฐาน
Returns:
DataFrame: DataFrame ที่มีการคำนวณ Rolling
"""
# สร้างข้อมูลตัวอย่าง - ราคาหุ้น
np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=100, freq='D')
df = pd.DataFrame({
'price': 100 + np.random.randn(100).cumsum()
}, index=dates)
# คำนวณ Moving Average หลายช่วงเวลา
df['MA5'] = df['price'].rolling(window=5).mean() # 5 วัน
df['MA10'] = df['price'].rolling(window=10).mean() # 10 วัน
df['MA20'] = df['price'].rolling(window=20).mean() # 20 วัน
# คำนวณ Rolling Standard Deviation (Volatility)
df['volatility'] = df['price'].rolling(window=20).std()
# คำนวณ Rolling Min/Max
df['rolling_max_10'] = df['price'].rolling(window=10).max()
df['rolling_min_10'] = df['price'].rolling(window=10).min()
print("DataFrame with Rolling Calculations:")
print(df.tail(10))
return df
# ตัวอย่างการใช้งาน
df_rolling = basic_rolling_calculations()
def custom_rolling_windows():
"""
แสดงวิธีปรับแต่ง Rolling Window แบบต่างๆ
Returns:
DataFrame: DataFrame ที่มีการปรับแต่ง Rolling
"""
# สร้างข้อมูล
dates = pd.date_range('2024-01-01', periods=50, freq='D')
df = pd.DataFrame({
'value': np.random.randn(50).cumsum() + 100
}, index=dates)
# min_periods: จำนวนค่าขั้นต่ำที่ต้องมีในการคำนวณ
df['MA7_default'] = df['value'].rolling(window=7).mean() # มี NaN 6 ตัวแรก
df['MA7_min3'] = df['value'].rolling(window=7, min_periods=3).mean() # มี NaN 2 ตัวแรก
# center: จัดค่ากลางให้อยู่ตรงกลางหน้าต่าง
df['MA7_center'] = df['value'].rolling(window=7, center=True).mean()
# ใช้ฟังก์ชันหลายตัวพร้อมกัน
df_agg = df['value'].rolling(window=10).agg(['mean', 'std', 'min', 'max'])
print("Rolling with different settings:")
print(df.head(10))
print("\nMultiple aggregations:")
print(df_agg.head(15))
return df, df_agg
# ตัวอย่างการใช้งาน
df_custom, df_agg = custom_rolling_windows()
def rolling_with_custom_function():
"""
แสดงการใช้ Rolling กับฟังก์ชันที่กำหนดเอง
Returns:
DataFrame: DataFrame ที่ใช้ Custom Function
"""
# สร้างข้อมูลราคาหุ้น
dates = pd.date_range('2024-01-01', periods=100, freq='D')
df = pd.DataFrame({
'open': 100 + np.random.randn(100).cumsum(),
'high': 102 + np.random.randn(100).cumsum(),
'low': 98 + np.random.randn(100).cumsum(),
'close': 100 + np.random.randn(100).cumsum(),
'volume': np.random.randint(1000000, 10000000, 100)
}, index=dates)
# ฟังก์ชันคำนวณ RSI (Relative Strength Index)
def calculate_rsi(prices, period=14):
"""
คำนวณ RSI
Args:
prices: Series ของราคา
period: จำนวนวันที่ใช้คำนวณ
Returns:
float: ค่า RSI
"""
if len(prices) < period:
return np.nan
delta = prices.diff()
gain = (delta.where(delta > 0, 0)).mean()
loss = (-delta.where(delta < 0, 0)).mean()
if loss == 0:
return 100
rs = gain / loss
rsi = 100 - (100 / (1 + rs))
return rsi
# ใช้ Custom Function กับ Rolling
df['RSI_14'] = df['close'].rolling(window=14).apply(
lambda x: calculate_rsi(x), raw=False
)
# ฟังก์ชันคำนวณ Price Range
def price_range(window):
"""คำนวณช่วงราคาในหน้าต่าง"""
return window.max() - window.min()
df['price_range_10'] = df['close'].rolling(window=10).apply(price_range)
# คำนวณ Volume-Weighted Average Price (VWAP)
df['typical_price'] = (df['high'] + df['low'] + df['close']) / 3
df['vwap_10'] = (
(df['typical_price'] * df['volume']).rolling(window=10).sum() /
df['volume'].rolling(window=10).sum()
)
print("Custom Rolling Calculations:")
print(df[['close', 'RSI_14', 'price_range_10', 'vwap_10']].tail(10))
return df
# ตัวอย่างการใช้งาน
df_custom = rolling_with_custom_function()
นอกจาก Rolling Window แล้ว Pandas ยังมีเทคนิคการคำนวณแบบ Expanding (ขยายหน้าต่าง) และ Exponentially Weighted Moving (ถ่วงน้ำหนักแบบเอ็กซ์โพเนนเชียล)
Expanding จะคำนวณค่าสถิติโดยรวมข้อมูลทั้งหมดตั้งแต่เริ่มต้นจนถึงจุดปัจจุบัน
โดยที่:
def expanding_calculations():
"""
แสดงการใช้ Expanding Window
Returns:
DataFrame: DataFrame ที่มีการคำนวณ Expanding
"""
# สร้างข้อมูลยอดขาย
dates = pd.date_range('2024-01-01', periods=30, freq='D')
df = pd.DataFrame({
'daily_sales': np.random.randint(1000, 5000, 30)
}, index=dates)
# คำนวณ Cumulative (สะสม)
df['cumulative_sales'] = df['daily_sales'].expanding().sum()
# คำนวณค่าเฉลี่ยสะสม
df['cumulative_avg'] = df['daily_sales'].expanding().mean()
# คำนวณค่าสูงสุดสะสม
df['cumulative_max'] = df['daily_sales'].expanding().max()
# คำนวณ Standard Deviation สะสม
df['cumulative_std'] = df['daily_sales'].expanding().std()
print("Expanding Calculations:")
print(df.head(15))
return df
# ตัวอย่างการใช้งาน
df_expanding = expanding_calculations()
EWM ให้น้ำหนักกับข้อมูลล่าสุดมากกว่าข้อมูลเก่า โดยใช้ Smoothing Factor (α)
โดยที่:
def exponential_weighted_calculations():
"""
แสดงการใช้ Exponentially Weighted Moving
Returns:
DataFrame: DataFrame ที่มีการคำนวณ EWM
"""
# สร้างข้อมูลราคาที่มีความผันผวน
dates = pd.date_range('2024-01-01', periods=100, freq='D')
df = pd.DataFrame({
'price': 100 + np.random.randn(100).cumsum()
}, index=dates)
# EWM ด้วย span (จำนวนวัน)
df['EMA_12'] = df['price'].ewm(span=12, adjust=False).mean()
df['EMA_26'] = df['price'].ewm(span=26, adjust=False).mean()
# คำนวณ MACD (Moving Average Convergence Divergence)
df['MACD'] = df['EMA_12'] - df['EMA_26']
df['Signal'] = df['MACD'].ewm(span=9, adjust=False).mean()
df['Histogram'] = df['MACD'] - df['Signal']
# EWM ด้วย alpha (0-1)
df['EMA_alpha'] = df['price'].ewm(alpha=0.3, adjust=False).mean()
# EWM Standard Deviation
df['EMA_std'] = df['price'].ewm(span=20, adjust=False).std()
# Bollinger Bands
df['BB_middle'] = df['price'].ewm(span=20, adjust=False).mean()
df['BB_upper'] = df['BB_middle'] + (2 * df['EMA_std'])
df['BB_lower'] = df['BB_middle'] - (2 * df['EMA_std'])
print("Exponential Weighted Moving:")
print(df[['price', 'EMA_12', 'EMA_26', 'MACD', 'Signal']].tail(10))
return df
# ตัวอย่างการใช้งาน
df_ewm = exponential_weighted_calculations()
| คุณสมบัติ | Rolling | Expanding | EWM |
|---|---|---|---|
| ขนาดหน้าต่าง | คงที่ | ขยายตามเวลา | ถ่วงน้ำหนัก |
| ข้อมูลเก่า | หลุดออกจากหน้าต่าง | รวมทั้งหมด | ลดน้ำหนักลง |
| ความไวต่อการเปลี่ยนแปลง | ปานกลาง | ต่ำ | สูง |
| การใช้งาน | Moving Average | Cumulative Stats | Trend Following |
| ความซับซ้อน | ต่ำ | ต่ำ | กลาง |
เมื่อทำงานกับข้อมูลจากหลายประเทศหรือข้อมูลการเงินระหว่างประเทศ การจัดการ Time Zone เป็นเรื่องสำคัญมาก
def working_with_timezones():
"""
แสดงวิธีจัดการ Time Zones
Returns:
DataFrame: DataFrame ที่มี Time Zone ต่างๆ
"""
# สร้างข้อมูลแบบ naive (ไม่มี timezone)
dates_naive = pd.date_range('2024-01-01 09:00', periods=5, freq='H')
df = pd.DataFrame({
'value': [100, 102, 101, 103, 105]
}, index=dates_naive)
print("Naive datetime (no timezone):")
print(df)
print(f"Timezone: {df.index.tz}")
# เพิ่ม timezone (localize)
df_bangkok = df.copy()
df_bangkok.index = df_bangkok.index.tz_localize('Asia/Bangkok')
print("\n\nWith Bangkok timezone:")
print(df_bangkok)
print(f"Timezone: {df_bangkok.index.tz}")
# แปลงเป็น timezone อื่น (convert)
df_ny = df_bangkok.copy()
df_ny.index = df_ny.index.tz_convert('America/New_York')
print("\n\nConverted to New York timezone:")
print(df_ny)
# สร้างข้อมูลพร้อม timezone ตั้งแต่แรก
dates_utc = pd.date_range(
'2024-01-01 00:00',
periods=5,
freq='H',
tz='UTC'
)
df_utc = pd.DataFrame({
'price': [100, 102, 101, 103, 105]
}, index=dates_utc)
print("\n\nCreated with UTC timezone:")
print(df_utc)
return df_bangkok, df_ny, df_utc
# ตัวอย่างการใช้งาน
df_bkk, df_ny, df_utc = working_with_timezones()
| Time Zone String | ตำแหน่ง | UTC Offset |
|---|---|---|
UTC |
สากล | +00:00 |
Asia/Bangkok |
กรุงเทพ | +07:00 |
Asia/Tokyo |
โตเกียว | +09:00 |
Asia/Shanghai |
เซี่ยงไฮ้ | +08:00 |
Europe/London |
ลอนดอน | +00:00/+01:00 |
America/New_York |
นิวยอร์ก | -05:00/-04:00 |
US/Pacific |
แปซิฟิก | -08:00/-07:00 |
การจัดการข้อมูลอนุกรมเวลาด้วย Pandas เป็นทักษะที่สำคัญมากในการวิเคราะห์ข้อมูล โดยเฉพาะในด้านการเงิน IoT และข้อมูลที่มีการบันทึกตามเวลา จุดสำคัญที่ต้องจำ:
pd.to_datetime() เพื่อแปลง String เป็น Datetime object ที่สามารถคำนวณได้การเชี่ยวชาญเรื่องเหล่านี้จะช่วยให้คุณสามารถวิเคราะห์ข้อมูลอนุกรมเวลาได้อย่างมีประสิทธิภาพและแม่นยำ
Pandas Official Documentation - Time Series / Date functionality
Python datetime module
McKinney, W. (2022). Python for Data Analysis, 3rd Edition. O'Reilly Media.
VanderPlas, J. (2016). Python Data Science Handbook. O'Reilly Media.
Pytz - World Timezone Definitions
Technical Analysis Library in Python (ta-lib)