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

หน้าต่างเลื่อน

คำนวณค่าเฉลี่ย ผลรวม และส่วนเบี่ยงเบนมาตรฐานแบบเลื่อนบนจำนวนแถวคงที่ด้วย rolling(n).mean() และเมธอดที่เกี่ยวข้อง

บทเรียน 1 จาก 413 ขั้นตอน

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

หน้าต่าง rolling คืออะไร

หน้าต่าง rolling (เรียกอีกอย่างว่าหน้าต่างเลื่อนหรือหน้าต่างเคลื่อนที่) ใช้คำนวณค่าสถิติบนหน้าต่างขนาดคงที่ของแถวที่อยู่ติดกัน โดยเลื่อนไปข้างหน้าทีละแถว ตัวอย่างเช่น ค่าเฉลี่ย rolling 7 วันจะแทนค่าของแต่ละวันด้วยค่าเฉลี่ยของวันนั้นและ 6 วันก่อนหน้า หน้าต่าง rolling เป็นพื้นฐานของ ค่าเฉลี่ยเคลื่อนที่ในงานการเงิน การทำให้ข้อมูลเซนเซอร์ที่มีสัญญาณรบกวนราบเรียบ และการคำนวณ ตัวชี้วัดย้อนหลังในแดชบอร์ดธุรกิจ

import pandas as pd
import numpy as np

# Simple example: 3-day rolling mean
data = pd.Series([10, 12, 15, 11, 9, 13, 16, 14, 12, 18],
                 index=pd.date_range('2024-01-01', periods=10))

rolling_mean = data.rolling(window=3).mean()
print('Original:')
print(data.values)
print('\n3-day rolling mean:')
print(rolling_mean.values.round(2))

เมธอด rolling() และพารามิเตอร์ window

Series.rolling(window=n) จะคืนออบเจ็กต์ Rolling พารามิเตอร์ window คือขนาดของหน้าต่างเลื่อน โดยระบุเป็นจำนวนแถว (สำหรับหน้าต่างจำนวนเต็ม) หรือช่วงเวลา เช่น '7D' (สำหรับ Series ที่มีดัชนีเวลา) หลังสร้างออบเจ็กต์ rolling แล้ว คุณสามารถต่อด้วยเมธอดรวมค่าใด ๆ ได้ เช่น .mean(), .sum(), .std(), .min(), .max() หรือแม้แต่ .apply(func) แถวแรกจำนวน window-1 แถวจะเป็น NaN เสมอ เพราะยังมีแถวก่อนหน้าไม่เพียงพอที่จะเติมเต็มหน้าต่าง

import pandas as pd
import numpy as np

prices = pd.Series(
    [100, 102, 98, 105, 110, 108, 115, 112, 120, 118],
    index=pd.date_range('2024-01-01', periods=10),
    name='price'
)

df = pd.DataFrame({'price': prices})
df['MA3'] = df['price'].rolling(3).mean()
df['MA7'] = df['price'].rolling(7).mean()
df['std3'] = df['price'].rolling(3).std()
print(df.round(2))

พารามิเตอร์ min_periods

โดยค่าเริ่มต้น rolling(n) ต้องมีค่าไม่ใช่ NaN ในหน้าต่างครบ n ค่าเสียก่อนจึงจะคำนวณผลลัพธ์ พารามิเตอร์ min_periods ใช้ลดข้อกำหนดนี้ได้ เช่น rolling(7, min_periods=3) จะคำนวณค่าเฉลี่ยทันทีที่มีค่าอย่างน้อย 3 ค่า ทำให้ได้ค่าที่ไม่ใช่ NaN เร็วขึ้นใน Series วิธีนี้มีประโยชน์เมื่อคุณต้องการให้มีค่าเฉลี่ยเคลื่อนที่ตั้งแต่ต้นอนุกรมเวลา แทนที่จะได้ NaN ใน n-1 แถวแรก

import pandas as pd
import numpy as np

prices = pd.Series([100, 102, 98, 105, 110, 108, 115],
                   index=pd.date_range('2024-01-01', periods=7))

# Default: first 6 rows are NaN
ma7_default = prices.rolling(7).mean()

# min_periods=3: compute mean once 3 values available
ma7_minperiods = prices.rolling(7, min_periods=3).mean()

df = pd.DataFrame({
    'price': prices,
    'MA7_default': ma7_default,
    'MA7_min3': ma7_minperiods
})
print(df.round(2))

ผลรวม rolling สำหรับยอดสะสม

rolling(n).sum() คำนวณผลรวมของ n แถวล่าสุด ณ แต่ละตำแหน่ง ผลรวม rolling 30 วันของยอดขายรายวันจะให้รายได้ย้อนหลังหนึ่งเดือนสำหรับแต่ละวัน ซึ่งให้ข้อมูลมากกว่ายอดรวมรายเดือนแบบคงที่ เพราะอัปเดตทุกวัน ผลรวม rolling มักใช้ในการวิเคราะห์การค้าปลีก (ยอดขาย 30 วันล่าสุด) การวิเคราะห์เว็บไซต์ (ผู้ใช้ที่ใช้งานใน 7 วันล่าสุด) และการเงิน (ปริมาณย้อนหลัง n ช่วงเวลา)

import pandas as pd
import numpy as np

np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=60)
daily_sales = pd.Series(np.random.randint(100, 500, 60), index=dates, name='daily_sales')

df = pd.DataFrame({'daily_sales': daily_sales})
df['trailing_7d'] = df['daily_sales'].rolling(7).sum()
df['trailing_30d'] = df['daily_sales'].rolling(30).sum()

print(df.tail(10).round(0))

ส่วนเบี่ยงเบนมาตรฐาน rolling สำหรับความผันผวน

ในงานการเงิน ความผันผวนวัดได้จากส่วนเบี่ยงเบนมาตรฐาน rolling ของผลตอบแทนรายวัน ค่า std rolling ที่สูงหมายถึงราคาผันผวนอย่างรุนแรง ส่วนค่า std rolling ที่ต่ำบ่งชี้ว่าราคาค่อนข้างคงที่ ตัวชี้วัดนี้ใช้ในการคำนวณความเสี่ยงสำหรับการกำหนดราคาออปชันและการจัดการพอร์ตการลงทุน สูตรคือ คำนวณผลตอบแทนลอการิทึมรายวันด้วย np.log(price/price.shift(1)) จากนั้นใช้ rolling(window).std()

import pandas as pd
import numpy as np

np.random.seed(0)
prices = pd.Series(
    100 * np.exp(np.cumsum(np.random.normal(0.001, 0.02, 120))),
    index=pd.date_range('2024-01-01', periods=120)
)

# Daily log returns
log_returns = np.log(prices / prices.shift(1))

# 20-day rolling volatility (annualised)
volatility = log_returns.rolling(20).std() * np.sqrt(252)

print('Last 5 rows of daily volatility:')
print(volatility.tail(5).round(4))

หน้าต่าง rolling ตามเวลา

แทนที่จะระบุจำนวนแถวคงที่ คุณสามารถระบุ ช่วงเวลาเป็นหน้าต่างได้: rolling('7D') หมายถึง “ข้อมูลในช่วง 7 วันตามปฏิทินล่าสุด” วิธีนี้จัดการอนุกรมเวลาที่มีช่วงเวลาไม่สม่ำเสมอ (เช่น ขาดข้อมูลช่วงสุดสัปดาห์หรือวันหยุด) ได้อย่างถูกต้องโดยอัตโนมัติ — หน้าต่างตามจำนวนแถวจะครอบคลุมช่วงเวลาตามปฏิทินแตกต่างกันเมื่อมีช่วงขาดหาย แต่หน้าต่างตามช่วงเวลาจะครอบคลุมข้อมูล 7 วันเสมอ Series ต้องมี DatetimeIndex จึงจะใช้หน้าต่างตามเวลาได้

import pandas as pd
import numpy as np

# Business-day index (no weekends)
biz_dates = pd.bdate_range('2024-01-01', periods=15)
sales = pd.Series(np.random.randint(100, 300, 15), index=biz_dates)

# 7-calendar-day window (variable row count near weekends)
df = pd.DataFrame({'sales': sales})
df['rolling_7d'] = sales.rolling('7D').mean()

print(df.round(1))

การใช้ rolling กับฟังก์ชันกำหนดเอง

rolling(n).apply(func) จะส่งแต่ละหน้าต่างเป็นอาร์เรย์ NumPy ไปยังฟังก์ชันกำหนดเองของคุณ วิธีนี้ช่วยให้คำนวณ rolling แบบใดก็ได้ที่ไม่มีอยู่ในการรวมค่าซึ่งมีมาให้ เช่น ค่าความเบี่ยงเบนสัมบูรณ์จากมัธยฐาน rolling ความเบ้ rolling หรือควอไทล์แรก rolling ฟังก์ชันต้องรับอาร์เรย์หนึ่งมิติและคืนค่าสเกลาร์ หมายเหตุ: apply ช้ากว่าเมธอดที่มีมาให้ เนื่องจากไม่สามารถทำงานแบบเวกเตอร์ได้

import pandas as pd
import numpy as np

prices = pd.Series(
    [100, 102, 98, 105, 110, 95, 115, 112, 120, 108],
    index=pd.date_range('2024-01-01', periods=10)
)

# Rolling range (max - min) over a 5-day window
def rolling_range(arr):
    return arr.max() - arr.min()

df = pd.DataFrame({'price': prices})
df['5d_range'] = prices.rolling(5).apply(rolling_range, raw=True)
print(df.round(2))

การใช้ rolling กับคอลัมน์ของ DataFrame

คุณสามารถใช้ rolling().mean() กับ DataFrame ได้โดยตรง เพื่อคำนวณค่าสถิติ rolling สำหรับคอลัมน์ตัวเลขทั้งหมดพร้อมกัน แต่ละคอลัมน์จะมีหน้าต่าง rolling ของตนเองและคำนวณแยกกัน วิธีนี้มีประโยชน์สำหรับคำนวณค่าเฉลี่ยเคลื่อนที่ของราคาหุ้นหลายรายการหรือยอดขายสินค้าหลายสายการผลิตในการดำเนินการครั้งเดียว โดยไม่ต้องวนซ้ำผ่านคอลัมน์

import pandas as pd
import numpy as np

np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=10)
df = pd.DataFrame({
    'AAPL': 100 + np.cumsum(np.random.randn(10)),
    'MSFT': 200 + np.cumsum(np.random.randn(10)),
    'GOOG': 150 + np.cumsum(np.random.randn(10))
}, index=dates)

# 3-day moving average of all three stocks
ma3 = df.rolling(3).mean()
print('3-day MA for all stocks:')
print(ma3.round(2))

การรวมค่าเฉลี่ย rolling เข้ากับข้อมูลเดิม

รูปแบบการแสดงผลที่ใช้กันทั่วไปคือการวาดทั้งอนุกรมเวลาดิบและค่าเฉลี่ย rolling บนแกนเดียวกัน ค่าเฉลี่ย rolling แสดงให้เห็น แนวโน้มด้วยการลดสัญญาณรบกวนรายวัน ขณะที่อนุกรมข้อมูลดิบแสดง ความผันผวน ช่องว่างระหว่างทั้งสองค่าบ่งบอกว่ามีสัญญาณรบกวนมากเพียงใด การเพิ่มค่าเฉลี่ย rolling ลงใน DataFrame ทำได้ง่ายเพียงกำหนดผลลัพธ์ให้กับคอลัมน์ใหม่

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

np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=60)
sales = pd.Series(
    200 + np.cumsum(np.random.randn(60) * 10),
    index=dates, name='Daily Sales'
)

df = pd.DataFrame({'sales': sales})
df['MA7'] = df['sales'].rolling(7).mean()
df['MA30'] = df['sales'].rolling(30).mean()

df.plot(figsize=(12, 5), title='Sales with 7-day and 30-day Moving Average')
plt.ylabel('Sales')
plt.show()

หน้าต่าง rolling แบบกึ่งกลาง

โดยค่าเริ่มต้น rolling จะใช้หน้าต่างแบบ ย้อนหลัง (แถวปัจจุบันและ n-1 แถวก่อนหน้า) การตั้งค่า center=True จะสร้างหน้าต่างแบบ กึ่งกลาง โดยให้แถวปัจจุบันอยู่ตรงกลางและใช้จำนวนแถวจากอดีตและอนาคตเท่ากัน หน้าต่างแบบกึ่งกลางให้ผลลัพธ์ที่ราบเรียบกว่า และเหมาะสำหรับ การทำให้ข้อมูลประวัติศาสตร์ราบเรียบแบบออฟไลน์ ซึ่งทราบค่าของอนาคตแล้ว แต่ไม่เหมาะกับการพยากรณ์แบบสด เพราะต้องใช้ข้อมูลในอนาคต

import pandas as pd
import numpy as np

np.random.seed(0)
data = pd.Series(
    np.sin(np.linspace(0, 4*3.14159, 30)) + np.random.normal(0, 0.3, 30)
)

df = pd.DataFrame({'signal': data})
df['trailing_MA5'] = data.rolling(5).mean()
df['centered_MA5'] = data.rolling(5, center=True).mean()

print('Comparison (first 8 rows):')
print(df.head(8).round(3))

หน้าต่างแบบเลื่อนสำหรับข้อมูล GroupBy

คุณสามารถคำนวณสถิติแบบเลื่อนแยกตามกลุ่มได้โดยใช้ groupby().rolling() ตัวอย่างเช่น การคำนวณรายได้แบบเลื่อน 7 วันต่อหมวดหมู่สินค้า หน้าต่างจะเริ่มนับใหม่เมื่อเริ่มกลุ่มแต่ละกลุ่ม ดังนั้นข้อมูลของสินค้าหนึ่งจะไม่ปะปนกับข้อมูลของอีกสินค้า หลังจากดำเนินการแบบเลื่อนแล้ว ให้ใช้ .reset_index(level=0, drop=True) เพื่อนำระดับกลุ่มส่วนเกินออกจากดัชนี และจัดผลลัพธ์ให้สอดคล้องกับ DataFrame เดิม

import pandas as pd
import numpy as np

np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=10)
df = pd.DataFrame({
    'date': list(dates) * 2,
    'product': ['A'] * 10 + ['B'] * 10,
    'sales': np.random.randint(50, 200, 20)
}).sort_values(['product', 'date'])

# 3-day rolling mean per product
df['rolling_mean'] = (df
    .groupby('product')['sales']
    .transform(lambda x: x.rolling(3).mean())
)
print(df.to_string(index=False))

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

ทดสอบความเข้าใจเกี่ยวกับหน้าต่างแบบเลื่อนจากบทเรียนนี้

ทบทวนบทเรียน

ในบทเรียนนี้ คุณได้เรียนรู้ว่า rolling(n) สร้างหน้าต่างเลื่อนที่มีแถวจำนวน n แถว ซึ่งคุณสามารถคำนวณ mean, sum, std, min, max หรือฟังก์ชันที่กำหนดเองได้ ส่วน จำนวนช่วงขั้นต่ำ จะลดจำนวนค่าขั้นต่ำที่ต้องใช้ในการคำนวณผลลัพธ์ และ การจัดกึ่งกลางเป็น True จะสร้างหน้าต่างที่จัดกึ่งกลางสำหรับการปรับเรียบแบบออฟไลน์ ต่อไปเราจะสำรวจหน้าต่างแบบขยาย ซึ่งเป็นสถิติสะสมที่ขยายจากจุดเริ่มต้นของ Series

เริ่มต้นได้ฟรี

เรียนรู้ Python ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
30
บทเรียน
120

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

บทเรียน “หน้าต่างเลื่อน” ฟรีหรือไม่

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

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

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

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

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

บทเรียน “หน้าต่างเลื่อน” ใช้เวลานานแค่ไหน

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

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

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

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

  1. หน้าต่างเลื่อน
  2. หน้าต่างสะสม
  3. ค่าเฉลี่ยเคลื่อนที่แบบถ่วงน้ำหนักเอ็กซ์โพเนนเชียล
  4. อันดับและเปอร์เซ็นไทล์ภายในกลุ่ม
← กลับไปที่ Pandas & NumPy Academy