0Pricing
Pandas & NumPy Academy · บทเรียน

การเลื่อนและคุณลักษณะหน่วงเวลา

สร้างคอลัมน์ค่าหน่วงและค่าล่วงหน้าด้วย shift() คำนวณการเปลี่ยนแปลงระหว่างช่วงเวลาด้วย diff() และคำนวณการเปลี่ยนแปลงเป็นเปอร์เซ็นต์

การเลื่อนและคุณลักษณะหน่วงเวลา เป็นบทเรียน Pandas & NumPy Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Pandas & NumPy Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Pandas & NumPy Academy มีบทเรียนทั้งหมด 4 บทเรียน

เหตุใดคุณลักษณะแล็กจึงสำคัญ

ในการวิเคราะห์อนุกรมเวลา ค่าของช่วงเวลาก่อนหน้า (เรียกว่า แล็ก) มักเป็นตัวทำนายค่าปัจจุบันที่ดีที่สุดตัวหนึ่ง ตัวอย่างเช่น ยอดขายเมื่อวานให้ข้อมูลที่เป็นประโยชน์เกี่ยวกับยอดขายวันนี้ การสร้างคอลัมน์แล็กช่วยให้คุณใช้ค่าในอดีตเป็นคุณลักษณะในแบบจำลองการเรียนรู้ของเครื่อง หรือใช้ในการวิเคราะห์ทางสถิติของสหสัมพันธ์อัตโนมัติ Pandas มี shift() สำหรับสร้างคุณลักษณะแล็กด้วยการเรียกใช้แบบเวกเตอร์เพียงครั้งเดียว

shift(): การเลื่อนค่าไปข้างหน้าหรือข้างหลัง

Series.shift(n) เลื่อนค่าทั้งหมด ลง ตามจำนวนตำแหน่ง n (ค่า n เป็นบวกจะสร้างแล็ก) และเติม NaN ให้ n แถวแรก หากส่งค่า n เป็นลบ ค่าจะถูกเลื่อน ขึ้น (สร้างค่าล่วงหน้า โดยเลื่อนค่าในอนาคตกลับมายังแถวปัจจุบัน) ดัชนียังคงเดิม — มีเพียงค่าที่ถูกเลื่อนตำแหน่ง

import pandas as pd
import numpy as np

df = pd.DataFrame(
    {'sales': [100, 120, 115, 130, 140, 125]},
    index=pd.date_range('2024-01-01', periods=6, freq='D')
)

# Lag-1: yesterday's sales
df['sales_lag1'] = df['sales'].shift(1)
# Lead-1: tomorrow's sales (shifted up)
df['sales_lead1'] = df['sales'].shift(-1)
print(df)

การสร้างคอลัมน์ Lag หลายคอลัมน์

โดยทั่วไป คุณจะสร้างฟีเจอร์ lag หลายรายการพร้อมกันสำหรับแมชชีนเลิร์นนิง เช่น lag-1, lag-7 (วันเดียวกันของสัปดาห์ก่อน) และ lag-30 (วันเดียวกันของเดือนก่อน) วิธีที่อ่านเข้าใจง่ายที่สุดคือสร้างฟีเจอร์เหล่านี้ภายในลูป แล้วกำหนดแต่ละรายการให้กับคอลัมน์ใหม่ ผลลัพธ์คือ DataFrame ที่มีทั้งซีรีส์เดิมและเวอร์ชัน lag ทั้งหมด พร้อมสำหรับการสร้างแบบจำลอง

for lag in [1, 2, 3, 7]:
    df[f'sales_lag{lag}'] = df['sales'].shift(lag)

print(df.columns.tolist())
# ['sales', 'sales_lag1', 'sales_lag2', 'sales_lag3', 'sales_lag7']

# Drop rows with NaN from the largest lag period
df_model = df.dropna()
print('Ready for modelling, shape:', df_model.shape)

shift() พร้อม freq สำหรับการเลื่อนตามเวลา

แทนที่จะเลื่อนด้วยจำนวนแถวแบบจำนวนเต็ม คุณสามารถเลื่อนด้วยช่วงเวลาโดยใช้พารามิเตอร์ freq ได้ df.shift(1, freq='ME') จะเลื่อนดัชนีไปข้างหน้าหนึ่งสิ้นเดือน โดยคงค่าเดิมไว้แต่เปลี่ยนดัชนี วิธีนี้มีประโยชน์สำหรับจัดแนวซีรีส์เวลาสองชุดที่เหลื่อมกันด้วยช่วงเวลาคงที่ โดยไม่ต้องจัดเรียงค่าใหม่

monthly = pd.Series(
    [100, 120, 115],
    index=pd.date_range('2024-01-31', periods=3, freq='ME')
)

# Shift the index forward by 1 month (values stay, index moves)
shifted_index = monthly.shift(1, freq='ME')
print('Original index:', monthly.index.tolist())
print('Shifted index: ', shifted_index.index.tolist())
# Original: [2024-01-31, 2024-02-29, 2024-03-31]
# Shifted:  [2024-02-29, 2024-03-31, 2024-04-30]

diff(): การเปลี่ยนแปลงระหว่างช่วงเวลา

Series.diff(n) คำนวณผลต่างระหว่างค่าหนึ่งกับค่าที่อยู่ก่อนหน้า n ตำแหน่ง: x[t] - x[t-n] โดยมักใช้คำนวณการเปลี่ยนแปลงรายวัน ผลต่างรายสัปดาห์ หรือการเปลี่ยนแปลงรายปี แถวแรกจำนวน n แถวจะเป็น NaN เนื่องจากไม่มีค่าก่อนหน้าให้ลบ

df['sales_diff1'] = df['sales'].diff(1)  # day-over-day change
df['sales_diff7'] = df['sales'].diff(7)  # week-over-week change

print(df[['sales', 'sales_diff1']].head())
#             sales  sales_diff1
# 2024-01-01    100          NaN
# 2024-01-02    120         20.0  <- +20 from yesterday
# 2024-01-03    115         -5.0  <- -5 from yesterday

pct_change(): การเปลี่ยนแปลงเป็นเปอร์เซ็นต์

Series.pct_change(n) คำนวณการเปลี่ยนแปลงสัมพัทธ์เป็นเปอร์เซ็นต์: (x[t] - x[t-n]) / x[t-n] วิธีนี้จำเป็นอย่างยิ่งสำหรับการวิเคราะห์ทางการเงิน (ผลตอบแทนรายวัน) การคำนวณอัตราการเติบโต และทุกกรณีที่การเปลี่ยนแปลงแบบสัมบูรณ์สื่อความหมายได้น้อยกว่าการเปลี่ยนแปลงแบบสัมพัทธ์ ให้คูณด้วย 100 เพื่อแปลงเป็นหน่วยเปอร์เซ็นต์

df['pct_chg'] = df['sales'].pct_change().round(3)
df['pct_chg_7d'] = df['sales'].pct_change(7).round(3)

print(df[['sales', 'pct_chg']].head())
#             sales  pct_chg
# 2024-01-01    100      NaN
# 2024-01-02    120    0.200  <- 20% increase
# 2024-01-03    115   -0.042  <- 4.2% decrease

การใช้ shift() ร่วมกับการคำนวณทางคณิตศาสตร์

คุณสามารถใช้ shift() ร่วมกับการคำนวณทางคณิตศาสตร์เพื่อสร้างฟีเจอร์เวลาที่คำนวณต่อยอดได้ ตัวอย่างเช่น อัตราส่วนระหว่างค่าของวันนี้กับค่าของสัปดาห์ก่อน ผลรวมสะสมตั้งแต่จุดเริ่มต้นที่กำหนด หรือผลต่างจากค่าของปีก่อน ทุกกรณีใช้รูปแบบเดียวกัน คือเลื่อนซีรีส์เดิม แล้วคำนวณแบบสมาชิกต่อสมาชิกกับค่าปัจจุบัน

# Week-over-week growth index (today / last week)
df['wow_ratio'] = (df['sales'] / df['sales'].shift(7)).round(3)

# Deviation from 3-day lag
df['dev_3d'] = df['sales'] - df['sales'].shift(3)

# Is today higher than yesterday? (boolean feature)
df['higher_than_yesterday'] = df['sales'] > df['sales'].shift(1)

print(df[['sales', 'wow_ratio', 'higher_than_yesterday']].head())

cumsum() และ cumprod() สำหรับฟีเจอร์สะสม

Series.cumsum() คำนวณผลรวมสะสมตั้งแต่แถวแรกจนถึงแต่ละแถว ส่วน Series.cumprod() คำนวณผลคูณสะสม ทั้งสองอย่างมีประโยชน์สำหรับรายได้สะสม ผลตอบแทนสะสม (การเติบโตแบบทบต้น) และยอดรวมสะสมตั้งแต่ต้นปี โดยไม่ต้องรับอาร์กิวเมนต์ และทำงานกับ Series เชิงตัวเลขหรือคอลัมน์ของ DataFrame ใดก็ได้

# Cumulative sales (year-to-date total)
df['ytd_sales'] = df['sales'].cumsum()

# Cumulative product: compound growth factor
returns = pd.Series([0.02, -0.01, 0.03, 0.01, -0.005])
df_ret = pd.DataFrame({'daily_return': returns})
df_ret['compound'] = (1 + df_ret['daily_return']).cumprod() - 1
print(df_ret)

ฟีเจอร์ Lag สำหรับแมชชีนเลิร์นนิง

เมื่อเตรียมข้อมูลซีรีส์เวลาสำหรับแมชชีนเลิร์นนิง ขั้นตอนวิศวกรรมฟีเจอร์มาตรฐานคือการสร้างเมทริกซ์ของฟีเจอร์ lag แต่ละคอลัมน์แทนค่าตัวแปรเป้าหมาย ณ ช่วงเวลาในอดีตที่แตกต่างกัน หลังจากสร้าง lag แล้ว ให้ลบแถวที่มี NaN (ซึ่งปรากฏในช่วงเริ่มต้นเนื่องจากไม่มีข้อมูลในอดีต) และแบ่งข้อมูลเป็นชุดฝึกกับชุดทดสอบ โดยไม่สับเปลี่ยนลำดับ เพื่อรักษาลำดับเวลา

def make_lag_matrix(series, n_lags):
    df_lags = pd.DataFrame({'y': series})
    for lag in range(1, n_lags + 1):
        df_lags[f'lag_{lag}'] = series.shift(lag)
    return df_lags.dropna()

lag_df = make_lag_matrix(df['sales'], n_lags=3)
print(lag_df)
# y    lag_1  lag_2  lag_3
# ...  ...    ...    ...

การเลื่อนค่าภายในกลุ่ม

เมื่อข้อมูลของคุณมีหลายเอนทิตี (เช่น มีสินค้าหรือภูมิภาคหลายรายการอยู่ใน DataFrame เดียวกัน) คุณต้องคำนวณการเลื่อนแยกกัน ภายใน กลุ่มของแต่ละเอนทิตี ใช้ groupby().shift() เพื่อให้ lag ของแถวแรกของสินค้า A เป็น NaN ไม่ใช่ค่าล่าสุดของสินค้า B การผสมกลุ่มเข้าด้วยกันโดยไม่ทำขั้นตอนนี้เป็นข้อผิดพลาดด้านข้อมูลรั่วไหลที่พบได้บ่อยและตรวจพบได้ยาก

df_multi = pd.DataFrame({
    'product': ['A', 'A', 'A', 'B', 'B', 'B'],
    'sales': [100, 120, 115, 200, 210, 195]
})

# WRONG: lag crosses product boundary
df_multi['lag_wrong'] = df_multi['sales'].shift(1)

# CORRECT: lag within each product
df_multi['lag_correct'] = df_multi.groupby('product')['sales'].shift(1)
print(df_multi)

การตีความเครื่องหมายของ pct_change

ค่า pct_change() ที่เป็นบวกหมายความว่าค่าปัจจุบัน สูงกว่าค่าก่อนหน้า ส่วนค่าที่เป็นลบหมายความว่าค่าปัจจุบันต่ำกว่า โปรดระวังการหารด้วยศูนย์เมื่อค่าก่อนหน้าเป็นศูนย์ ผลลัพธ์จะเป็น NaN หรือ inf ขึ้นอยู่กับเครื่องหมายของค่าปัจจุบัน ใช้ replace([float('inf'), float('-inf')], float('nan')) เพื่อล้างค่าที่เป็นอนันต์หลังใช้ pct_change()

import numpy as np

s = pd.Series([0, 100, 50, 200])
chg = s.pct_change()
print(chg)
# 0      NaN  <- no prior value
# 1      inf  <- 0 -> 100 (division by zero)
# 2    -0.5   <- 100 -> 50 (-50%)
# 3     3.0   <- 50 -> 200 (+300%)

# Clean infinite values
chg_clean = chg.replace([float('inf'), float('-inf')], float('nan'))
print(chg_clean)

ตรวจสอบความเข้าใจอย่างรวดเร็ว

ทดสอบความเข้าใจเกี่ยวกับการเลื่อนค่าและฟีเจอร์ lag จากบทเรียนนี้

สรุปบทเรียน

ในบทเรียนนี้ คุณได้เรียนรู้ว่า shift(n) สร้าง ฟีเจอร์ lag โดยเลื่อนค่าลงจำนวน n ตำแหน่ง diff(n) คำนวณ การเปลี่ยนแปลงแบบสัมบูรณ์ระหว่างช่วงเวลา pct_change(n) คำนวณ การเปลี่ยนแปลงสัมพัทธ์เป็นเปอร์เซ็นต์ และเมื่อทำงานกับหลายกลุ่ม คุณต้องใช้ groupby().shift() เพื่อหลีกเลี่ยงข้อมูลรั่วไหล บทถัดไป เราจะดึงฟีเจอร์ตามเวลาโดยใช้ตัวเข้าถึง .dt

คำถามที่พบบ่อย

บทเรียน “การเลื่อนและคุณลักษณะหน่วงเวลา” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การเลื่อนและคุณลักษณะหน่วงเวลา” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Pandas & NumPy Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Pandas & NumPy Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การเลื่อนและคุณลักษณะหน่วงเวลา”

สร้างคอลัมน์ค่าหน่วงและค่าล่วงหน้าด้วย shift() คำนวณการเปลี่ยนแปลงระหว่างช่วงเวลาด้วย diff() และคำนวณการเปลี่ยนแปลงเป็นเปอร์เซ็นต์ คุณปฏิบัติ Pandas & NumPy Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Pandas & NumPy Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Pandas & NumPy Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “การเลื่อนและคุณลักษณะหน่วงเวลา” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Pandas & NumPy Academy นี้ได้ไหม

ได้ บทเรียน Pandas & NumPy Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. DatetimeIndex และช่วงเวลา
  2. การปรับความถี่อนุกรมเวลา
  3. การเลื่อนและคุณลักษณะหน่วงเวลา
  4. การแยกคุณลักษณะตามเวลา
← กลับไปที่ Pandas & NumPy Academy