1from __future__ import annotations
2
3from typing import (
4 TYPE_CHECKING,
5 Any,
6 Concatenate,
7 Literal,
8 Self,
9 final,
10 overload,
11)
12
13from pandas.util._decorators import set_module
14
15from pandas.core.indexers.objects import (
16 BaseIndexer,
17 ExpandingIndexer,
18 GroupByIndexer,
19)
20from pandas.core.window.rolling import (
21 BaseWindowGroupBy,
22 RollingAndExpandingMixin,
23)
24
25if TYPE_CHECKING:
26 from collections.abc import Callable
27
28 from pandas._typing import (
29 P,
30 QuantileInterpolation,
31 T,
32 WindowingRankType,
33 )
34
35 from pandas import (
36 DataFrame,
37 Series,
38 )
39 from pandas.core.generic import NDFrame
40
41
42@set_module("pandas.api.typing")
43class Expanding(RollingAndExpandingMixin):
44 """
45 Provide expanding window calculations.
46
47 An expanding window yields the value of an aggregation statistic with all the data
48 available up to that point in time.
49
50 Parameters
51 ----------
52 min_periods : int, default 1
53 Minimum number of observations in window required to have a value;
54 otherwise, result is ``np.nan``.
55
56 method : str {'single', 'table'}, default 'single'
57 Execute the rolling operation per single column or row (``'single'``)
58 or over the entire object (``'table'``).
59
60 This argument is only implemented when specifying ``engine='numba'``
61 in the method call.
62
63 Returns
64 -------
65 pandas.api.typing.Expanding
66 An instance of Expanding for further expanding window calculations,
67 e.g. using the ``sum`` method.
68
69 See Also
70 --------
71 rolling : Provides rolling window calculations.
72 ewm : Provides exponential weighted functions.
73
74 Notes
75 -----
76 See :ref:`Windowing Operations <window.expanding>` for further usage details
77 and examples.
78
79 Examples
80 --------
81 >>> df = pd.DataFrame({"B": [0, 1, 2, np.nan, 4]})
82 >>> df
83 B
84 0 0.0
85 1 1.0
86 2 2.0
87 3 NaN
88 4 4.0
89
90 **min_periods**
91
92 Expanding sum with 1 vs 3 observations needed to calculate a value.
93
94 >>> df.expanding(1).sum()
95 B
96 0 0.0
97 1 1.0
98 2 3.0
99 3 3.0
100 4 7.0
101 >>> df.expanding(3).sum()
102 B
103 0 NaN
104 1 NaN
105 2 3.0
106 3 3.0
107 4 7.0
108 """
109
110 _attributes: list[str] = ["min_periods", "method"]
111
112 def __init__(
113 self,
114 obj: NDFrame,
115 min_periods: int = 1,
116 method: str = "single",
117 selection=None,
118 ) -> None:
119 super().__init__(
120 obj=obj,
121 min_periods=min_periods,
122 method=method,
123 selection=selection,
124 )
125
126 def _get_window_indexer(self) -> BaseIndexer:
127 """
128 Return an indexer class that will compute the window start and end bounds
129 """
130 return ExpandingIndexer()
131
132 def aggregate(self, func=None, *args, **kwargs):
133 """
134 Aggregate using one or more operations over the specified axis.
135
136 Accepts a function, string name, list, or dict of functions and
137 applies them cumulatively over all data points seen so far.
138
139 Parameters
140 ----------
141 func : function, str, list or dict
142 Function to use for aggregating the data. If a function, must either
143 work when passed a Series/Dataframe or when passed to
144 Series/Dataframe.apply.
145
146 Accepted combinations are:
147
148 - function
149 - string function name
150 - list of functions and/or function names, e.g. ``[np.sum, 'mean']``
151 - dict of axis labels -> functions, function names or list of such.
152
153 *args
154 Positional arguments to pass to `func`.
155 **kwargs
156 Keyword arguments to pass to `func`.
157
158 Returns
159 -------
160 scalar, Series or DataFrame
161
162 The return can be:
163
164 * scalar : when Series.agg is called with single function
165 * Series : when DataFrame.agg is called with a single function
166 * DataFrame : when DataFrame.agg is called with several functions
167
168 See Also
169 --------
170 DataFrame.aggregate : Similar DataFrame method.
171 Series.aggregate : Similar Series method.
172
173 Notes
174 -----
175 The aggregation operations are always performed over an axis, either the
176 index (default) or the column axis. This behavior is different from
177 `numpy` aggregation functions (`mean`, `median`, `prod`, `sum`, `std`,
178 `var`), where the default is to compute the aggregation of the flattened
179 array, e.g., ``numpy.mean(arr_2d)`` as opposed to
180 ``numpy.mean(arr_2d, axis=0)``.
181
182 `agg` is an alias for `aggregate`. Use the alias.
183
184 Functions that mutate the passed object can produce unexpected
185 behavior or errors and are not supported. See :ref:`gotchas.udf-mutation`
186 for more details.
187
188 A passed user-defined-function will be passed a Series for evaluation.
189
190 If ``func`` defines an index relabeling, ``axis`` must be ``0`` or ``index``.
191
192 Examples
193 --------
194 >>> df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6], "C": [7, 8, 9]})
195 >>> df
196 A B C
197 0 1 4 7
198 1 2 5 8
199 2 3 6 9
200
201 >>> df.expanding(2).sum()
202 A B C
203 0 NaN NaN NaN
204 1 3.0 9.0 15.0
205 2 6.0 15.0 24.0
206
207 >>> df.expanding(2).agg({"A": "sum", "B": "min"})
208 A B
209 0 NaN NaN
210 1 3.0 4.0
211 2 6.0 4.0
212 """
213 return super().aggregate(func, *args, **kwargs)
214
215 agg = aggregate
216
217 def count(self, numeric_only: bool = False):
218 """
219 Calculate the expanding count of non NaN observations.
220
221 At each point in time, returns the number of non-NaN values seen
222 so far. This is useful for tracking data availability across an
223 expanding window.
224
225 Parameters
226 ----------
227 numeric_only : bool, default False
228 Include only float, int, boolean columns.
229
230 Returns
231 -------
232 Series or DataFrame
233 Return type is the same as the original object with ``np.float64`` dtype.
234
235 See Also
236 --------
237 Series.expanding : Calling expanding with Series data.
238 DataFrame.expanding : Calling expanding with DataFrames.
239 Series.count : Aggregating count for Series.
240 DataFrame.count : Aggregating count for DataFrame.
241
242 Examples
243 --------
244 >>> ser = pd.Series([1, 2, 3, 4], index=["a", "b", "c", "d"])
245 >>> ser.expanding().count()
246 a 1.0
247 b 2.0
248 c 3.0
249 d 4.0
250 dtype: float64
251 """
252 return super().count(numeric_only=numeric_only)
253
254 def apply(
255 self,
256 func: Callable[..., Any],
257 raw: bool = False,
258 engine: Literal["cython", "numba"] | None = None,
259 engine_kwargs: dict[str, bool] | None = None,
260 args: tuple[Any, ...] | None = None,
261 kwargs: dict[str, Any] | None = None,
262 ):
263 """
264 Calculate the expanding custom aggregation function.
265
266 Applies a user-defined function over all data points seen so far.
267
268 Parameters
269 ----------
270 func : function
271 Must produce a single value from an ndarray input if ``raw=True``
272 or a single value from a Series if ``raw=False``. Can also accept a
273 Numba JIT function with ``engine='numba'`` specified.
274
275 raw : bool, default False
276 * ``False`` : passes each row or column as a Series to the
277 function.
278 * ``True`` : the passed function will receive ndarray objects instead.
279 Pandas-only attributes such as ``.iloc`` or ``.index`` are not
280 available on ndarrays and will raise ``AttributeError`` if used
281 inside ``func``.
282
283 If you are just applying a NumPy reduction function this will
284 achieve much better performance.
285
286 engine : str, default None
287 * ``'cython'`` : Runs rolling apply through C-extensions from cython.
288 * ``'numba'`` : Runs rolling apply through JIT compiled code from numba.
289 Only available when ``raw`` is set to ``True``.
290 * ``None`` : Defaults to ``'cython'`` or globally setting
291 ``compute.use_numba``
292
293 engine_kwargs : dict, default None
294 * For ``'cython'`` engine, there are no accepted ``engine_kwargs``
295 * For ``'numba'`` engine, the engine can accept ``nogil``
296 and ``parallel`` dictionary keys. The values must either be ``True`` or
297 ``False``. The default ``engine_kwargs`` for the ``'numba'`` engine is
298 ``{'nogil': False, 'parallel': False}`` and will be
299 applied to both the ``func`` and the ``apply`` rolling aggregation.
300
301 args : tuple, default None
302 Positional arguments to be passed into func.
303
304 kwargs : dict, default None
305 Keyword arguments to be passed into func.
306
307 Returns
308 -------
309 Series or DataFrame
310 Return type is the same as the original object with ``np.float64`` dtype.
311
312 See Also
313 --------
314 Series.expanding : Calling expanding with Series data.
315 DataFrame.expanding : Calling expanding with DataFrames.
316 Series.apply : Aggregating apply for Series.
317 DataFrame.apply : Aggregating apply for DataFrame.
318
319 Examples
320 --------
321 >>> ser = pd.Series([1, 2, 3, 4], index=["a", "b", "c", "d"])
322 >>> ser.expanding().apply(lambda s: s.max() - 2 * s.min())
323 a -1.0
324 b 0.0
325 c 1.0
326 d 2.0
327 dtype: float64
328 """
329 return super().apply(
330 func,
331 raw=raw,
332 engine=engine,
333 engine_kwargs=engine_kwargs,
334 args=args,
335 kwargs=kwargs,
336 )
337
338 @overload
339 def pipe(
340 self,
341 func: Callable[Concatenate[Self, P], T],
342 *args: P.args,
343 **kwargs: P.kwargs,
344 ) -> T: ...
345
346 @overload
347 def pipe(
348 self,
349 func: tuple[Callable[..., T], str],
350 *args: Any,
351 **kwargs: Any,
352 ) -> T: ...
353
354 @final
355 def pipe(
356 self,
357 func: Callable[Concatenate[Self, P], T] | tuple[Callable[..., T], str],
358 *args: Any,
359 **kwargs: Any,
360 ) -> T:
361 """
362 Apply a ``func`` with arguments to this Expanding object and return its result.
363
364 Use `.pipe` when you want to improve readability by chaining together
365 functions that expect Series, DataFrames, GroupBy, Rolling, Expanding or
366 Resampler
367 objects.
368 Instead of writing
369
370 >>> h = lambda x, arg2, arg3: x + 1 - arg2 * arg3
371 >>> g = lambda x, arg1: x * 5 / arg1
372 >>> f = lambda x: x**4
373 >>> df = pd.DataFrame(
374 ... {"A": [1, 2, 3, 4]}, index=pd.date_range("2012-08-02", periods=4)
375 ... )
376 >>> h(g(f(df.rolling("2D")), arg1=1), arg2=2, arg3=3) # doctest: +SKIP
377
378 You can write
379
380 >>> (
381 ... df.rolling("2D").pipe(f).pipe(g, arg1=1).pipe(h, arg2=2, arg3=3)
382 ... ) # doctest: +SKIP
383
384 which is much more readable.
385
386 Parameters
387 ----------
388 func : callable or tuple of (callable, str)
389 Function to apply to this Expanding object or, alternatively,
390 a `(callable, data_keyword)` tuple where `data_keyword` is a
391 string indicating the keyword of `callable` that expects the
392 Expanding object.
393 *args : iterable, optional
394 Positional arguments passed into `func`.
395 **kwargs : dict, optional
396 A dictionary of keyword arguments passed into `func`.
397
398 Returns
399 -------
400 Expanding
401 The original object with the function `func` applied.
402
403 See Also
404 --------
405 Series.pipe : Apply a function with arguments to a series.
406 DataFrame.pipe: Apply a function with arguments to a dataframe.
407 apply : Apply function to each group instead of to the
408 full Expanding object.
409
410 Notes
411 -----
412 See more `here
413 <https://pandas.pydata.org/pandas-docs/stable/user_guide/groupby.html#piping-function-calls>`_
414
415 Examples
416 --------
417
418 >>> df = pd.DataFrame(
419 ... {"A": [1, 2, 3, 4]}, index=pd.date_range("2012-08-02", periods=4)
420 ... )
421 >>> df
422 A
423 2012-08-02 1
424 2012-08-03 2
425 2012-08-04 3
426 2012-08-05 4
427
428 To get the difference between each expanding window's maximum and minimum
429 value in one pass, you can do
430
431 >>> df.expanding().pipe(lambda x: x.max() - x.min())
432 A
433 2012-08-02 0.0
434 2012-08-03 1.0
435 2012-08-04 2.0
436 2012-08-05 3.0
437 """
438 return super().pipe(func, *args, **kwargs)
439
440 def sum(
441 self,
442 numeric_only: bool = False,
443 engine: Literal["cython", "numba"] | None = None,
444 engine_kwargs: dict[str, bool] | None = None,
445 ):
446 """
447 Calculate the expanding sum.
448
449 At each point in time, returns the cumulative sum of all values
450 observed up to that point, respecting the ``min_periods`` threshold.
451
452 Parameters
453 ----------
454 numeric_only : bool, default False
455 Include only float, int, boolean columns.
456
457 engine : str, default None
458 * ``'cython'`` : Runs the operation through C-extensions from cython.
459 * ``'numba'`` : Runs the operation through JIT compiled code from numba.
460 * ``None`` : Defaults to ``'cython'`` or globally setting
461 ``compute.use_numba``
462
463 engine_kwargs : dict, default None
464 * For ``'cython'`` engine, there are no accepted ``engine_kwargs``
465 * For ``'numba'`` engine, the engine can accept ``nogil``
466 and ``parallel`` dictionary keys. The values must either be ``True`` or
467 ``False``. The default ``engine_kwargs`` for the ``'numba'`` engine is
468 ``{'nogil': False, 'parallel': False}``
469
470 Returns
471 -------
472 Series or DataFrame
473 Return type is the same as the original object with ``np.float64`` dtype.
474
475 See Also
476 --------
477 Series.expanding : Calling expanding with Series data.
478 DataFrame.expanding : Calling expanding with DataFrames.
479 Series.sum : Aggregating sum for Series.
480 DataFrame.sum : Aggregating sum for DataFrame.
481
482 Notes
483 -----
484 See :ref:`window.numba_engine` and :ref:`enhancingperf.numba` for extended
485 documentation and performance considerations for the Numba engine.
486
487 Examples
488 --------
489 >>> ser = pd.Series([1, 2, 3, 4], index=["a", "b", "c", "d"])
490 >>> ser.expanding().sum()
491 a 1.0
492 b 3.0
493 c 6.0
494 d 10.0
495 dtype: float64
496 """
497 return super().sum(
498 numeric_only=numeric_only,
499 engine=engine,
500 engine_kwargs=engine_kwargs,
501 )
502
503 def max(
504 self,
505 numeric_only: bool = False,
506 engine: Literal["cython", "numba"] | None = None,
507 engine_kwargs: dict[str, bool] | None = None,
508 ):
509 """
510 Calculate the expanding maximum.
511
512 At each point in time, returns the maximum value observed up to
513 that point, respecting the ``min_periods`` threshold.
514
515 Parameters
516 ----------
517 numeric_only : bool, default False
518 Include only float, int, boolean columns.
519
520 engine : str, default None
521 * ``'cython'`` : Runs the operation through C-extensions from cython.
522 * ``'numba'`` : Runs the operation through JIT compiled code from numba.
523 * ``None`` : Defaults to ``'cython'`` or globally setting
524 ``compute.use_numba``
525
526 engine_kwargs : dict, default None
527 * For ``'cython'`` engine, there are no accepted ``engine_kwargs``
528 * For ``'numba'`` engine, the engine can accept ``nogil``
529 and ``parallel`` dictionary keys. The values must either be ``True`` or
530 ``False``. The default ``engine_kwargs`` for the ``'numba'`` engine is
531 ``{'nogil': False, 'parallel': False}``
532
533 Returns
534 -------
535 Series or DataFrame
536 Return type is the same as the original object with ``np.float64`` dtype.
537
538 See Also
539 --------
540 Series.expanding : Calling expanding with Series data.
541 DataFrame.expanding : Calling expanding with DataFrames.
542 Series.max : Aggregating max for Series.
543 DataFrame.max : Aggregating max for DataFrame.
544
545 Notes
546 -----
547 See :ref:`window.numba_engine` and :ref:`enhancingperf.numba` for extended
548 documentation and performance considerations for the Numba engine.
549
550 Examples
551 --------
552 >>> ser = pd.Series([3, 2, 1, 4], index=["a", "b", "c", "d"])
553 >>> ser.expanding().max()
554 a 3.0
555 b 3.0
556 c 3.0
557 d 4.0
558 dtype: float64
559 """
560 return super().max(
561 numeric_only=numeric_only,
562 engine=engine,
563 engine_kwargs=engine_kwargs,
564 )
565
566 def min(
567 self,
568 numeric_only: bool = False,
569 engine: Literal["cython", "numba"] | None = None,
570 engine_kwargs: dict[str, bool] | None = None,
571 ):
572 """
573 Calculate the expanding minimum.
574
575 At each point in time, returns the minimum value observed up to
576 that point, respecting the ``min_periods`` threshold.
577
578 Parameters
579 ----------
580 numeric_only : bool, default False
581 Include only float, int, boolean columns.
582
583 engine : str, default None
584 * ``'cython'`` : Runs the operation through C-extensions from cython.
585 * ``'numba'`` : Runs the operation through JIT compiled code from numba.
586 * ``None`` : Defaults to ``'cython'`` or globally setting
587 ``compute.use_numba``
588
589 engine_kwargs : dict, default None
590 * For ``'cython'`` engine, there are no accepted ``engine_kwargs``
591 * For ``'numba'`` engine, the engine can accept ``nogil``
592 and ``parallel`` dictionary keys. The values must either be ``True`` or
593 ``False``. The default ``engine_kwargs`` for the ``'numba'`` engine is
594 ``{'nogil': False, 'parallel': False}``
595
596 Returns
597 -------
598 Series or DataFrame
599 Return type is the same as the original object with ``np.float64`` dtype.
600
601 See Also
602 --------
603 Series.expanding : Calling expanding with Series data.
604 DataFrame.expanding : Calling expanding with DataFrames.
605 Series.min : Aggregating min for Series.
606 DataFrame.min : Aggregating min for DataFrame.
607
608 Notes
609 -----
610 See :ref:`window.numba_engine` and :ref:`enhancingperf.numba` for extended
611 documentation and performance considerations for the Numba engine.
612
613 Examples
614 --------
615 >>> ser = pd.Series([2, 3, 4, 1], index=["a", "b", "c", "d"])
616 >>> ser.expanding().min()
617 a 2.0
618 b 2.0
619 c 2.0
620 d 1.0
621 dtype: float64
622 """
623 return super().min(
624 numeric_only=numeric_only,
625 engine=engine,
626 engine_kwargs=engine_kwargs,
627 )
628
629 def mean(
630 self,
631 numeric_only: bool = False,
632 engine: Literal["cython", "numba"] | None = None,
633 engine_kwargs: dict[str, bool] | None = None,
634 ):
635 """
636 Calculate the expanding mean.
637
638 At each point in time, returns the arithmetic mean of all values
639 observed up to that point, respecting the ``min_periods`` threshold.
640
641 Parameters
642 ----------
643 numeric_only : bool, default False
644 Include only float, int, boolean columns.
645
646 engine : str, default None
647 * ``'cython'`` : Runs the operation through C-extensions from cython.
648 * ``'numba'`` : Runs the operation through JIT compiled code from numba.
649 * ``None`` : Defaults to ``'cython'`` or globally setting
650 ``compute.use_numba``
651
652 engine_kwargs : dict, default None
653 * For ``'cython'`` engine, there are no accepted ``engine_kwargs``
654 * For ``'numba'`` engine, the engine can accept ``nogil``
655 and ``parallel`` dictionary keys. The values must either be ``True`` or
656 ``False``. The default ``engine_kwargs`` for the ``'numba'`` engine is
657 ``{'nogil': False, 'parallel': False}``
658
659 Returns
660 -------
661 Series or DataFrame
662 Return type is the same as the original object with ``np.float64`` dtype.
663
664 See Also
665 --------
666 Series.expanding : Calling expanding with Series data.
667 DataFrame.expanding : Calling expanding with DataFrames.
668 Series.mean : Aggregating mean for Series.
669 DataFrame.mean : Aggregating mean for DataFrame.
670
671 Notes
672 -----
673 See :ref:`window.numba_engine` and :ref:`enhancingperf.numba` for extended
674 documentation and performance considerations for the Numba engine.
675
676 Examples
677 --------
678 >>> ser = pd.Series([1, 2, 3, 4], index=["a", "b", "c", "d"])
679 >>> ser.expanding().mean()
680 a 1.0
681 b 1.5
682 c 2.0
683 d 2.5
684 dtype: float64
685 """
686 return super().mean(
687 numeric_only=numeric_only,
688 engine=engine,
689 engine_kwargs=engine_kwargs,
690 )
691
692 def median(
693 self,
694 numeric_only: bool = False,
695 engine: Literal["cython", "numba"] | None = None,
696 engine_kwargs: dict[str, bool] | None = None,
697 ):
698 """
699 Calculate the expanding median.
700
701 At each point in time, returns the median of all values observed
702 up to that point, respecting the ``min_periods`` threshold.
703
704 Parameters
705 ----------
706 numeric_only : bool, default False
707 Include only float, int, boolean columns.
708
709 engine : str, default None
710 * ``'cython'`` : Runs the operation through C-extensions from cython.
711 * ``'numba'`` : Runs the operation through JIT compiled code from numba.
712 * ``None`` : Defaults to ``'cython'`` or globally setting
713 ``compute.use_numba``
714
715 engine_kwargs : dict, default None
716 * For ``'cython'`` engine, there are no accepted ``engine_kwargs``
717 * For ``'numba'`` engine, the engine can accept ``nogil``
718 and ``parallel`` dictionary keys. The values must either be ``True`` or
719 ``False``. The default ``engine_kwargs`` for the ``'numba'`` engine is
720 ``{'nogil': False, 'parallel': False}``
721
722 Returns
723 -------
724 Series or DataFrame
725 Return type is the same as the original object with ``np.float64`` dtype.
726
727 See Also
728 --------
729 Series.expanding : Calling expanding with Series data.
730 DataFrame.expanding : Calling expanding with DataFrames.
731 Series.median : Aggregating median for Series.
732 DataFrame.median : Aggregating median for DataFrame.
733
734 Notes
735 -----
736 See :ref:`window.numba_engine` and :ref:`enhancingperf.numba` for extended
737 documentation and performance considerations for the Numba engine.
738
739 Examples
740 --------
741 >>> ser = pd.Series([1, 2, 3, 4], index=["a", "b", "c", "d"])
742 >>> ser.expanding().median()
743 a 1.0
744 b 1.5
745 c 2.0
746 d 2.5
747 dtype: float64
748 """
749 return super().median(
750 numeric_only=numeric_only,
751 engine=engine,
752 engine_kwargs=engine_kwargs,
753 )
754
755 def std(
756 self,
757 ddof: int = 1,
758 numeric_only: bool = False,
759 engine: Literal["cython", "numba"] | None = None,
760 engine_kwargs: dict[str, bool] | None = None,
761 ):
762 """
763 Calculate the expanding standard deviation.
764
765 At each point in time, returns the sample standard deviation of all
766 values observed up to that point, using ``ddof`` degrees of freedom
767 correction.
768
769 Parameters
770 ----------
771 ddof : int, default 1
772 Delta Degrees of Freedom. The divisor used in calculations
773 is ``N - ddof``, where ``N`` represents the number of elements.
774
775 numeric_only : bool, default False
776 Include only float, int, boolean columns.
777
778 engine : str, default None
779 * ``'cython'`` : Runs the operation through C-extensions from cython.
780 * ``'numba'`` : Runs the operation through JIT compiled code from numba.
781 * ``None`` : Defaults to ``'cython'`` or globally setting
782 ``compute.use_numba``
783
784 engine_kwargs : dict, default None
785 * For ``'cython'`` engine, there are no accepted ``engine_kwargs``
786 * For ``'numba'`` engine, the engine can accept ``nogil``
787 and ``parallel`` dictionary keys. The values must either be ``True`` or
788 ``False``. The default ``engine_kwargs`` for the ``'numba'`` engine is
789 ``{'nogil': False, 'parallel': False}``
790
791 Returns
792 -------
793 Series or DataFrame
794 Return type is the same as the original object with ``np.float64`` dtype.
795
796 See Also
797 --------
798 numpy.std : Equivalent method for NumPy array.
799 Series.expanding : Calling expanding with Series data.
800 DataFrame.expanding : Calling expanding with DataFrames.
801 Series.std : Aggregating std for Series.
802 DataFrame.std : Aggregating std for DataFrame.
803
804 Notes
805 -----
806 The default ``ddof`` of 1 used in :meth:`Series.std` is different
807 than the default ``ddof`` of 0 in :func:`numpy.std`.
808
809 A minimum of one period is required for the rolling calculation.
810
811 Examples
812 --------
813 >>> s = pd.Series([5, 5, 6, 7, 5, 5, 5])
814
815 >>> s.expanding(3).std()
816 0 NaN
817 1 NaN
818 2 0.577350
819 3 0.957427
820 4 0.894427
821 5 0.836660
822 6 0.786796
823 dtype: float64
824 """
825 return super().std(
826 ddof=ddof,
827 numeric_only=numeric_only,
828 engine=engine,
829 engine_kwargs=engine_kwargs,
830 )
831
832 def var(
833 self,
834 ddof: int = 1,
835 numeric_only: bool = False,
836 engine: Literal["cython", "numba"] | None = None,
837 engine_kwargs: dict[str, bool] | None = None,
838 ):
839 """
840 Calculate the expanding variance.
841
842 At each point in time, returns the sample variance of all values
843 observed up to that point, using ``ddof`` degrees of freedom
844 correction.
845
846 Parameters
847 ----------
848 ddof : int, default 1
849 Delta Degrees of Freedom. The divisor used in calculations
850 is ``N - ddof``, where ``N`` represents the number of elements.
851
852 numeric_only : bool, default False
853 Include only float, int, boolean columns.
854
855 engine : str, default None
856 * ``'cython'`` : Runs the operation through C-extensions from cython.
857 * ``'numba'`` : Runs the operation through JIT compiled code from numba.
858 * ``None`` : Defaults to ``'cython'`` or globally setting
859 ``compute.use_numba``
860
861 engine_kwargs : dict, default None
862 * For ``'cython'`` engine, there are no accepted ``engine_kwargs``
863 * For ``'numba'`` engine, the engine can accept ``nogil``
864 and ``parallel`` dictionary keys. The values must either be ``True`` or
865 ``False``. The default ``engine_kwargs`` for the ``'numba'`` engine is
866 ``{'nogil': False, 'parallel': False}``
867
868 Returns
869 -------
870 Series or DataFrame
871 Return type is the same as the original object with ``np.float64`` dtype.
872
873 See Also
874 --------
875 numpy.var : Equivalent method for NumPy array.
876 Series.expanding : Calling expanding with Series data.
877 DataFrame.expanding : Calling expanding with DataFrames.
878 Series.var : Aggregating var for Series.
879 DataFrame.var : Aggregating var for DataFrame.
880
881 Notes
882 -----
883 The default ``ddof`` of 1 used in :meth:`Series.var` is different
884 than the default ``ddof`` of 0 in :func:`numpy.var`.
885
886 A minimum of one period is required for the rolling calculation.
887
888 Examples
889 --------
890 >>> s = pd.Series([5, 5, 6, 7, 5, 5, 5])
891
892 >>> s.expanding(3).var()
893 0 NaN
894 1 NaN
895 2 0.333333
896 3 0.916667
897 4 0.800000
898 5 0.700000
899 6 0.619048
900 dtype: float64
901 """
902 return super().var(
903 ddof=ddof,
904 numeric_only=numeric_only,
905 engine=engine,
906 engine_kwargs=engine_kwargs,
907 )
908
909 def sem(self, ddof: int = 1, numeric_only: bool = False):
910 """
911 Calculate the expanding standard error of mean.
912
913 The standard error is computed as ``std / sqrt(N)`` over all data
914 points seen so far, where ``N`` is the number of observations.
915
916 Parameters
917 ----------
918 ddof : int, default 1
919 Delta Degrees of Freedom. The divisor used in calculations
920 is ``N - ddof``, where ``N`` represents the number of elements.
921
922 numeric_only : bool, default False
923 Include only float, int, boolean columns.
924
925 Returns
926 -------
927 Series or DataFrame
928 Return type is the same as the original object with ``np.float64`` dtype.
929
930 See Also
931 --------
932 Series.expanding : Calling expanding with Series data.
933 DataFrame.expanding : Calling expanding with DataFrames.
934 Series.sem : Aggregating sem for Series.
935 DataFrame.sem : Aggregating sem for DataFrame.
936
937 Notes
938 -----
939 A minimum of one period is required for the calculation.
940
941 Examples
942 --------
943 >>> s = pd.Series([0, 1, 2, 3])
944
945 >>> s.expanding().sem()
946 0 NaN
947 1 0.500000
948 2 0.577350
949 3 0.645497
950 dtype: float64
951 """
952 return super().sem(ddof=ddof, numeric_only=numeric_only)
953
954 def skew(self, numeric_only: bool = False):
955 """
956 Calculate the expanding unbiased skewness.
957
958 Computes the third standardized moment over all data points seen
959 so far, measuring the asymmetry of the distribution.
960
961 Parameters
962 ----------
963 numeric_only : bool, default False
964 Include only float, int, boolean columns.
965
966 Returns
967 -------
968 Series or DataFrame
969 Return type is the same as the original object with ``np.float64`` dtype.
970
971 See Also
972 --------
973 scipy.stats.skew : Third moment of a probability density.
974 Series.expanding : Calling expanding with Series data.
975 DataFrame.expanding : Calling expanding with DataFrames.
976 Series.skew : Aggregating skew for Series.
977 DataFrame.skew : Aggregating skew for DataFrame.
978
979 Notes
980 -----
981 A minimum of three periods is required for the rolling calculation.
982
983 Examples
984 --------
985 >>> ser = pd.Series([-1, 0, 2, -1, 2], index=["a", "b", "c", "d", "e"])
986 >>> ser.expanding().skew()
987 a NaN
988 b NaN
989 c 0.935220
990 d 1.414214
991 e 0.315356
992 dtype: float64
993 """
994 return super().skew(numeric_only=numeric_only)
995
996 def kurt(self, numeric_only: bool = False):
997 """
998 Calculate the expanding Fisher's definition of kurtosis without bias.
999
1000 Measures the tailedness of the distribution over all data points
1001 seen so far. A minimum of four periods is required.
1002
1003 Parameters
1004 ----------
1005 numeric_only : bool, default False
1006 Include only float, int, boolean columns.
1007
1008 Returns
1009 -------
1010 Series or DataFrame
1011 Return type is the same as the original object with ``np.float64`` dtype.
1012
1013 See Also
1014 --------
1015 scipy.stats.kurtosis : Reference SciPy method.
1016 Series.expanding : Calling expanding with Series data.
1017 DataFrame.expanding : Calling expanding with DataFrames.
1018 Series.kurt : Aggregating kurt for Series.
1019 DataFrame.kurt : Aggregating kurt for DataFrame.
1020
1021 Notes
1022 -----
1023 A minimum of four periods is required for the calculation.
1024
1025 Examples
1026 --------
1027 The example below will show a rolling calculation with a window size of
1028 four matching the equivalent function call using `scipy.stats`.
1029
1030 >>> arr = [1, 2, 3, 4, 999]
1031 >>> import scipy.stats
1032 >>> print(f"{scipy.stats.kurtosis(arr[:-1], bias=False):.6f}")
1033 -1.200000
1034 >>> print(f"{scipy.stats.kurtosis(arr, bias=False):.6f}")
1035 4.999874
1036 >>> s = pd.Series(arr)
1037 >>> s.expanding(4).kurt()
1038 0 NaN
1039 1 NaN
1040 2 NaN
1041 3 -1.200000
1042 4 4.999874
1043 dtype: float64
1044 """
1045 return super().kurt(numeric_only=numeric_only)
1046
1047 def first(self, numeric_only: bool = False):
1048 """
1049 Calculate the expanding First (left-most) element of the window.
1050
1051 At each point in time, returns the first value in the expanding
1052 window, which is the earliest observation in the data.
1053
1054 Parameters
1055 ----------
1056 numeric_only : bool, default False
1057 Include only float, int, boolean columns.
1058
1059 Returns
1060 -------
1061 Series or DataFrame
1062 Return type is the same as the original object with ``np.float64`` dtype.
1063
1064 See Also
1065 --------
1066 GroupBy.first : Similar method for GroupBy objects.
1067 Expanding.last : Method to get the last element in each window.
1068
1069 Examples
1070 --------
1071 The example below will show an expanding calculation with a window size of
1072 three.
1073
1074 >>> s = pd.Series(range(5))
1075 >>> s.expanding(3).first()
1076 0 NaN
1077 1 NaN
1078 2 0.0
1079 3 0.0
1080 4 0.0
1081 dtype: float64
1082 """
1083 return super().first(numeric_only=numeric_only)
1084
1085 def last(self, numeric_only: bool = False):
1086 """
1087 Calculate the expanding Last (right-most) element of the window.
1088
1089 At each point in time, returns the last value in the expanding
1090 window, which is the most recent observation in the data.
1091
1092 Parameters
1093 ----------
1094 numeric_only : bool, default False
1095 Include only float, int, boolean columns.
1096
1097 Returns
1098 -------
1099 Series or DataFrame
1100 Return type is the same as the original object with ``np.float64`` dtype.
1101
1102 See Also
1103 --------
1104 GroupBy.last : Similar method for GroupBy objects.
1105 Expanding.first : Method to get the first element in each window.
1106
1107 Examples
1108 --------
1109 The example below will show an expanding calculation with a window size of
1110 three.
1111
1112 >>> s = pd.Series(range(5))
1113 >>> s.expanding(3).last()
1114 0 NaN
1115 1 NaN
1116 2 2.0
1117 3 3.0
1118 4 4.0
1119 dtype: float64
1120 """
1121 return super().last(numeric_only=numeric_only)
1122
1123 def quantile(
1124 self,
1125 q: float,
1126 interpolation: QuantileInterpolation = "linear",
1127 numeric_only: bool = False,
1128 ):
1129 """
1130 Calculate the expanding quantile.
1131
1132 At each step the specified quantile is computed from all prior
1133 observations, using the given interpolation method for values
1134 between data points.
1135
1136 Parameters
1137 ----------
1138 q : float
1139 Quantile to compute. 0 <= quantile <= 1.
1140
1141 interpolation : {'linear', 'lower', 'higher', 'midpoint', 'nearest'}
1142 This optional parameter specifies the interpolation method to use,
1143 when the desired quantile lies between two data points `i` and `j`:
1144
1145 * linear: `i + (j - i) * fraction`, where `fraction` is the
1146 fractional part of the index surrounded by `i` and `j`.
1147 * lower: `i`.
1148 * higher: `j`.
1149 * nearest: `i` or `j` whichever is nearest.
1150 * midpoint: (`i` + `j`) / 2.
1151
1152 numeric_only : bool, default False
1153 Include only float, int, boolean columns.
1154
1155 Returns
1156 -------
1157 Series or DataFrame
1158 Return type is the same as the original object with ``np.float64`` dtype.
1159
1160 See Also
1161 --------
1162 Series.expanding : Calling expanding with Series data.
1163 DataFrame.expanding : Calling expanding with DataFrames.
1164 Series.quantile : Aggregating quantile for Series.
1165 DataFrame.quantile : Aggregating quantile for DataFrame.
1166
1167 Examples
1168 --------
1169 >>> ser = pd.Series([1, 2, 3, 4, 5, 6], index=["a", "b", "c", "d", "e", "f"])
1170 >>> ser.expanding(min_periods=4).quantile(0.25)
1171 a NaN
1172 b NaN
1173 c NaN
1174 d 1.75
1175 e 2.00
1176 f 2.25
1177 dtype: float64
1178 """
1179 return super().quantile(
1180 q=q,
1181 interpolation=interpolation,
1182 numeric_only=numeric_only,
1183 )
1184
1185 def rank(
1186 self,
1187 method: WindowingRankType = "average",
1188 ascending: bool = True,
1189 pct: bool = False,
1190 numeric_only: bool = False,
1191 ):
1192 """
1193 Calculate the expanding rank.
1194
1195 Each value is ranked relative to all prior observations, with
1196 configurable tie-breaking and optional percentile normalization.
1197
1198 Parameters
1199 ----------
1200 method : {'average', 'min', 'max'}, default 'average'
1201 How to rank the group of records that have the same value (i.e. ties):
1202
1203 * average: average rank of the group
1204 * min: lowest rank in the group
1205 * max: highest rank in the group
1206
1207 ascending : bool, default True
1208 Whether or not the elements should be ranked in ascending order.
1209 pct : bool, default False
1210 Whether or not to display the returned rankings in percentile
1211 form.
1212 numeric_only : bool, default False
1213 Include only float, int, boolean columns.
1214
1215 Returns
1216 -------
1217 Series or DataFrame
1218 Return type is the same as the original object with ``np.float64`` dtype.
1219
1220 See Also
1221 --------
1222 Series.expanding : Calling expanding with Series data.
1223 DataFrame.expanding : Calling expanding with DataFrames.
1224 Series.rank : Aggregating rank for Series.
1225 DataFrame.rank : Aggregating rank for DataFrame.
1226
1227 Examples
1228 --------
1229 >>> s = pd.Series([1, 4, 2, 3, 5, 3])
1230 >>> s.expanding().rank()
1231 0 1.0
1232 1 2.0
1233 2 2.0
1234 3 3.0
1235 4 5.0
1236 5 3.5
1237 dtype: float64
1238
1239 >>> s.expanding().rank(method="max")
1240 0 1.0
1241 1 2.0
1242 2 2.0
1243 3 3.0
1244 4 5.0
1245 5 4.0
1246 dtype: float64
1247
1248 >>> s.expanding().rank(method="min")
1249 0 1.0
1250 1 2.0
1251 2 2.0
1252 3 3.0
1253 4 5.0
1254 5 3.0
1255 dtype: float64
1256 """
1257 return super().rank(
1258 method=method,
1259 ascending=ascending,
1260 pct=pct,
1261 numeric_only=numeric_only,
1262 )
1263
1264 def nunique(
1265 self,
1266 numeric_only: bool = False,
1267 ):
1268 """
1269 Calculate the expanding nunique.
1270
1271 .. versionadded:: 3.0.0
1272
1273 Parameters
1274 ----------
1275 numeric_only : bool, default False
1276 Include only float, int, boolean columns.
1277
1278 Returns
1279 -------
1280 Series or DataFrame
1281 Return type is the same as the original object with ``np.float64`` dtype.
1282
1283 See Also
1284 --------
1285 Series.expanding : Calling expanding with Series data.
1286 DataFrame.expanding : Calling expanding with DataFrames.
1287 Series.nunique : Aggregating nunique for Series.
1288 DataFrame.nunique : Aggregating nunique for DataFrame.
1289
1290 Examples
1291 --------
1292 >>> s = pd.Series([1, 4, 2, 3, 5, 3])
1293 >>> s.expanding().nunique()
1294 0 1.0
1295 1 2.0
1296 2 3.0
1297 3 4.0
1298 4 5.0
1299 5 5.0
1300 dtype: float64
1301 """
1302 return super().nunique(
1303 numeric_only=numeric_only,
1304 )
1305
1306 def cov(
1307 self,
1308 other: DataFrame | Series | None = None,
1309 pairwise: bool | None = None,
1310 ddof: int = 1,
1311 numeric_only: bool = False,
1312 ):
1313 """
1314 Calculate the expanding sample covariance.
1315
1316 When ``other`` is provided, computes pairwise covariance between
1317 ``self`` and ``other``; otherwise computes all pairwise covariances
1318 of the columns.
1319
1320 Parameters
1321 ----------
1322 other : Series or DataFrame, optional
1323 If not supplied then will default to self and produce pairwise
1324 output.
1325 pairwise : bool, default None
1326 If False then only matching columns between self and other will be
1327 used and the output will be a DataFrame.
1328 If True then all pairwise combinations will be calculated and the
1329 output will be a MultiIndexed DataFrame in the case of DataFrame
1330 inputs. In the case of missing elements, only complete pairwise
1331 observations will be used.
1332 ddof : int, default 1
1333 Delta Degrees of Freedom. The divisor used in calculations
1334 is ``N - ddof``, where ``N`` represents the number of elements.
1335 numeric_only : bool, default False
1336 Include only float, int, boolean columns.
1337
1338 Returns
1339 -------
1340 Series or DataFrame
1341 Return type is the same as the original object with ``np.float64`` dtype.
1342
1343 See Also
1344 --------
1345 Series.expanding : Calling expanding with Series data.
1346 DataFrame.expanding : Calling expanding with DataFrames.
1347 Series.cov : Aggregating cov for Series.
1348 DataFrame.cov : Aggregating cov for DataFrame.
1349
1350 Examples
1351 --------
1352 >>> ser1 = pd.Series([1, 2, 3, 4], index=["a", "b", "c", "d"])
1353 >>> ser2 = pd.Series([10, 11, 13, 16], index=["a", "b", "c", "d"])
1354 >>> ser1.expanding().cov(ser2)
1355 a NaN
1356 b 0.500000
1357 c 1.500000
1358 d 3.333333
1359 dtype: float64
1360 """
1361 return super().cov(
1362 other=other,
1363 pairwise=pairwise,
1364 ddof=ddof,
1365 numeric_only=numeric_only,
1366 )
1367
1368 def corr(
1369 self,
1370 other: DataFrame | Series | None = None,
1371 pairwise: bool | None = None,
1372 ddof: int = 1,
1373 numeric_only: bool = False,
1374 ):
1375 """
1376 Calculate the expanding correlation.
1377
1378 Uses Pearson's correlation over all data points seen so far.
1379
1380 Parameters
1381 ----------
1382 other : Series or DataFrame, optional
1383 If not supplied then will default to self and produce pairwise
1384 output.
1385 pairwise : bool, default None
1386 If False then only matching columns between self and other will be
1387 used and the output will be a DataFrame.
1388 If True then all pairwise combinations will be calculated and the
1389 output will be a MultiIndexed DataFrame in the case of DataFrame
1390 inputs. In the case of missing elements, only complete pairwise
1391 observations will be used.
1392 ddof : int, default 1
1393 Delta Degrees of Freedom. The divisor used in calculations
1394 is ``N - ddof``, where ``N`` represents the number of elements.
1395
1396 numeric_only : bool, default False
1397 Include only float, int, boolean columns.
1398
1399 Returns
1400 -------
1401 Series or DataFrame
1402 Return type is the same as the original object with ``np.float64`` dtype.
1403
1404 See Also
1405 --------
1406 cov : Similar method to calculate covariance.
1407 numpy.corrcoef : NumPy Pearson's correlation calculation.
1408 Series.expanding : Calling expanding with Series data.
1409 DataFrame.expanding : Calling expanding with DataFrames.
1410 Series.corr : Aggregating corr for Series.
1411 DataFrame.corr : Aggregating corr for DataFrame.
1412
1413 Notes
1414 -----
1415
1416 This function uses Pearson's definition of correlation
1417 (https://en.wikipedia.org/wiki/Pearson_correlation_coefficient).
1418
1419 When `other` is not specified, the output will be self correlation (e.g.
1420 all 1's), except for :class:`~pandas.DataFrame` inputs with `pairwise`
1421 set to `True`.
1422
1423 Function will return ``NaN`` for correlations of equal valued sequences;
1424 this is the result of a 0/0 division error.
1425
1426 When `pairwise` is set to `False`, only matching columns between `self` and
1427 `other` will be used.
1428
1429 When `pairwise` is set to `True`, the output will be a MultiIndex DataFrame
1430 with the original index on the first level, and the `other` DataFrame
1431 columns on the second level.
1432
1433 In the case of missing elements, only complete pairwise observations
1434 will be used.
1435
1436 Examples
1437 --------
1438 >>> ser1 = pd.Series([1, 2, 3, 4], index=["a", "b", "c", "d"])
1439 >>> ser2 = pd.Series([10, 11, 13, 16], index=["a", "b", "c", "d"])
1440 >>> ser1.expanding().corr(ser2)
1441 a NaN
1442 b 1.000000
1443 c 0.981981
1444 d 0.975900
1445 dtype: float64
1446 """
1447 return super().corr(
1448 other=other,
1449 pairwise=pairwise,
1450 ddof=ddof,
1451 numeric_only=numeric_only,
1452 )
1453
1454
1455@set_module("pandas.api.typing")
1456class ExpandingGroupBy(BaseWindowGroupBy, Expanding):
1457 """
1458 Provide an expanding groupby implementation.
1459 """
1460
1461 _attributes = Expanding._attributes + BaseWindowGroupBy._attributes
1462
1463 def _get_window_indexer(self) -> GroupByIndexer:
1464 """
1465 Return an indexer class that will compute the window start and end bounds
1466
1467 Returns
1468 -------
1469 GroupByIndexer
1470 """
1471 window_indexer = GroupByIndexer(
1472 groupby_indices=self._grouper.indices,
1473 window_indexer=ExpandingIndexer,
1474 )
1475 return window_indexer