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