Genişleyen Pencereler
expanding().sum() kullanarak başlangıçtan her noktaya kadar tüm satırları içeren kümülatif istatistikleri hesaplayın.
Genişleyen Pencereler, CoddyKit'te ücretsiz bir Pandas & NumPy Academy dersidir. Bu, 4 dersinin 2. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, Pandas & NumPy Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Pandas & NumPy Academy kursu toplamda 4 dersten oluşur.
Bu dersin bazı bölümleri henüz çevrilmemiş olup İngilizce olarak gösterilmektedir.
What Is an Expanding Window?
An expanding window includes all rows from the very beginning of the Series up to the current row — the window grows with each new row rather than staying fixed. At row 0 it contains only one value; at row 5 it contains six values; at row 100 it contains 101 values. Expanding windows are used to compute cumulative statistics that represent the running total, running average, or running maximum from the start of the dataset to the current point in time.
import pandas as pd
import numpy as np
sales = pd.Series(
[100, 150, 120, 200, 180, 160, 220, 190],
index=pd.date_range('2024-01-01', periods=8)
)
# Expanding mean — grows with each row
df = pd.DataFrame({'sales': sales})
df['cumulative_mean'] = df['sales'].expanding().mean()
print(df)The expanding() Method
Series.expanding(min_periods=1) returns an Expanding object. The min_periods parameter (default 1) sets the minimum number of observations required for the first non-NaN result. Unlike rolling(n), the window in expanding() is not fixed — it always starts at the beginning. Chain any aggregation: .sum(), .mean(), .std(), .min(), .max().
import pandas as pd
import numpy as np
np.random.seed(42)
monthly_revenue = pd.Series(
np.random.randint(500, 1500, 12),
index=pd.date_range('2024-01', periods=12, freq='ME'),
name='revenue'
)
df = pd.DataFrame({'revenue': monthly_revenue})
df['cumsum'] = df['revenue'].expanding().sum()
df['cummean'] = df['revenue'].expanding().mean()
df['cummax'] = df['revenue'].expanding().max()
df['cummin'] = df['revenue'].expanding().min()
print(df)Pandas cumsum, cumprod, cummax, cummin
For the most common cumulative statistics, Pandas provides direct methods on Series and DataFrame without needing expanding(): cumsum(), cumprod(), cummax(), and cummin(). These are optimised implementations that are slightly faster than their expanding() equivalents. Use these shortcuts for typical business metrics like year-to-date revenue (cumsum) or all-time maximum price (cummax).
import pandas as pd
import numpy as np
prices = pd.Series(
[100, 95, 110, 105, 120, 115, 130, 125],
index=pd.date_range('2024-01-01', periods=8)
)
df = pd.DataFrame({'price': prices})
df['cummax'] = df['price'].cummax() # all-time high
df['cummin'] = df['price'].cummin() # all-time low
df['cumsum'] = df['price'].cumsum() # cumulative total
df['cumprod'] = (1 + df['price'].pct_change()).cumprod() # growth index
print(df.round(3))Year-to-Date Calculation with Expanding
A classic use of expanding windows is year-to-date (YTD) revenue. For each day, you want the sum of all revenue from January 1st of the current year up to that day. This is just cumsum() applied within each year group. Implement it with groupby(year).cumsum() — the cumsum resets at the start of each calendar year while accumulating through the year.
import pandas as pd
import numpy as np
np.random.seed(0)
dates = pd.date_range('2023-01-01', '2024-06-30', freq='ME')
daily = pd.DataFrame({
'date': dates,
'revenue': np.random.randint(100, 500, len(dates))
})
# Year-to-date cumulative revenue
daily['year'] = daily['date'].dt.year
daily['ytd_revenue'] = daily.groupby('year')['revenue'].cumsum()
daily = daily.drop(columns='year')
print(daily.tail(10).to_string(index=False))Expanding Window Standard Deviation
expanding().std() computes the running standard deviation using all data from the start to the current row. This is useful for monitoring whether the variability of a metric is increasing or decreasing over time — for example, tracking whether a product's daily sales are becoming more or less predictable as the business matures. Unlike rolling std (which only reflects recent variability), expanding std captures the full historical dispersion.
import pandas as pd
import numpy as np
np.random.seed(42)
sales = pd.Series(
np.concatenate([
np.random.normal(100, 5, 30), # stable period
np.random.normal(100, 25, 30) # volatile period
]),
index=pd.date_range('2024-01-01', periods=60)
)
df = pd.DataFrame({'sales': sales})
df['expanding_std'] = df['sales'].expanding().std()
df['rolling_30d_std'] = df['sales'].rolling(30).std()
print(df.tail(10).round(2))Comparing Rolling vs Expanding
The key distinction: rolling windows reflect recent performance (last n days) and are insensitive to long-ago data, while expanding windows incorporate all history and thus converge slowly toward stable values. Use rolling when you care about recent trends (a 7-day moving average is more responsive to recent changes than a 90-day one). Use expanding when you want all-time statistics or YTD metrics that must never forget earlier data.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(10)
data = pd.Series(
np.random.randn(60).cumsum() + 50,
index=pd.date_range('2024-01-01', periods=60)
)
df = pd.DataFrame({'value': data})
df['rolling_10'] = data.rolling(10).mean()
df['expanding'] = data.expanding().mean()
df.plot(figsize=(12, 5), title='Rolling 10-day Mean vs. Expanding Mean')
plt.ylabel('Value')
plt.show()Expanding Apply for Custom Cumulative Stats
expanding().apply(func) applies a custom function to all data from the start to the current row, just like rolling().apply(). This enables cumulative statistics not available as built-ins — for example, the cumulative coefficient of variation (std/mean), the running median, or a cumulative Sharpe ratio. The function receives a NumPy array of all values seen so far and must return a scalar.
import pandas as pd
import numpy as np
np.random.seed(0)
returns = pd.Series(
np.random.normal(0.001, 0.02, 60),
index=pd.date_range('2024-01-01', periods=60)
)
# Cumulative Sharpe ratio (mean/std of returns)
def sharpe(arr):
if len(arr) < 2:
return float('nan')
return arr.mean() / arr.std() * (252 ** 0.5) # annualised
df = pd.DataFrame({'returns': returns})
df['cum_sharpe'] = df['returns'].expanding().apply(sharpe, raw=True)
print(df.tail(8).round(4))Expanding Windows with NaN Handling
Expanding windows skip NaN values by default — a NaN in the middle of the Series is ignored when computing the cumulative sum or mean. You can check this with skipna=True (the default in most Pandas aggregations). When you have time series with genuine missing values (e.g. no trading on weekends), expanding statistics will be computed only from the non-NaN values seen so far, which is usually the desired behaviour.
import pandas as pd
import numpy as np
data = pd.Series([10, np.nan, 20, 30, np.nan, 40, 50])
# cumsum skips NaN by default
df = pd.DataFrame({'value': data})
df['cumsum'] = df['value'].cumsum() # NaN propagates in cumsum!
df['expanding_sum'] = df['value'].expanding().sum() # NaN skipped
print(df)
print('\nNote: cumsum propagates NaN; expanding().sum() skips it.')Expanding Windows for Running Benchmarks
Expanding windows are ideal for computing running benchmarks: the all-time maximum, the best-quarter-ever, or the lowest error rate since launch. These KPIs require remembering all historical values — a rolling window would forget old records. Using cummax() or cummin() returns the running best (or worst) at each point, making it easy to track when new records were set.
import pandas as pd
import numpy as np
np.random.seed(5)
sales = pd.Series(
np.random.randint(100, 300, 20),
index=pd.date_range('2024-01-01', periods=20),
name='daily_sales'
)
df = pd.DataFrame({'sales': sales})
df['all_time_max'] = df['sales'].cummax()
df['new_record'] = df['sales'] == df['all_time_max']
print('Days where a new sales record was set:')
print(df[df['new_record']].drop(columns='new_record'))Practical Example: Cumulative Returns
In finance, cumulative returns show how much an investment has grown from the start date to each subsequent date. Starting from daily percentage returns, the cumulative product of (1 + daily_return) gives the total growth factor. An expanding product is more natural than a rolling product here — you want to track total growth since inception, not just over the last n days.
import pandas as pd
import numpy as np
np.random.seed(7)
start_price = 100
daily_returns = pd.Series(
np.random.normal(0.0005, 0.015, 252),
index=pd.date_range('2024-01-01', periods=252)
)
# Cumulative return = product of (1 + r_i)
cum_returns = (1 + daily_returns).cumprod()
portfolio_value = start_price * cum_returns
print(f'Start value: ${start_price:.2f}')
print(f'End value: ${portfolio_value.iloc[-1]:.2f}')
print(f'Total return: {(portfolio_value.iloc[-1]/start_price - 1)*100:.1f}%')When to Use Expanding vs Rolling vs cumsum
Guidelines for choosing the right approach:
- Use
cumsum() / cummax() / cummin()for simple cumulative aggregations — they are the fastest option. - Use
expanding().mean() / std()when you need cumulative running averages or variance. - Use
expanding().apply(custom_func)for complex all-time statistics not available as built-ins. - Use
rolling(n)instead of expanding when only recent history should influence the current value.
Quick Check
Test your understanding of expanding windows from this lesson.
Lesson Recap
In this lesson you learned: expanding() computes cumulative statistics over a growing window from the start of the Series, cumsum/cummax/cummin are optimised shortcuts for common cumulative operations, and expanding windows are ideal for all-time records, YTD metrics, and cumulative investment returns. Next up we explore exponentially weighted moving averages (EWMA) — giving more weight to recent observations.
Sıkça Sorulan Sorular
“Genişleyen Pencereler” dersi ücretsiz mi?
Evet — “Genişleyen Pencereler” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve Pandas & NumPy Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Pandas & NumPy Academy kursu toplamda 4 dersten oluşur.
“Genişleyen Pencereler” dersinde ne öğreneceğim?
expanding().sum() kullanarak başlangıçtan her noktaya kadar tüm satırları içeren kümülatif istatistikleri hesaplayın. Pandas & NumPy Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
Pandas & NumPy Academy öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te Pandas & NumPy Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 2. dersidir.
“Genişleyen Pencereler” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu Pandas & NumPy Academy dersinde kod yazıp çalıştırabilir miyim?
Evet. Her Pandas & NumPy Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- Kayan Pencereler
- Genişleyen Pencereler
- Üstel Ağırlıklı Hareketli Ortalama
- Gruplar İçinde Sıra ve Yüzdelik Dilim