It looks like a bug in older Pandas version. I could reproduce on an old installation Python 3.6.2 64 bit on win32, Pandas 1.0.3, numpy 1.15.4:

>>> s3.rolling(20,min_periods=3).kurt().tail(10)
890         9.591071
891         9.591071
892         9.591071
893         9.591071
894        19.663685
895        15.248361
896        40.444894
897      1368.233241
898    251407.375343
899    902540.031652
dtype: float64

It seems to be fixed on my newer version, Python 3.8.4 64 bit, Pandas 1.2.2, numpy 1.20.1:

>>> s3.rolling(20,min_periods=3).kurt().tail(10)
890     9.591067
891     9.591067
892     9.591067
893     9.591067
894    19.663666
895    14.872262
896    14.147158
897    16.716989
898     7.037037
899    20.000000
dtype: float64

both installations on the same Windows 10 machine.

I cannot say which component (Pandas or numpy) is the cause. As your tests using numpy.stats.kurtosis give correct result, I would suspect Pandas, but without further analysis by Pandas experts (and I am not one) I cannot be affirmative.

IMHO, the most reasonable solution is either to upgrade your system, or add a fresh new independant Python installation with the last possible Pandas version.

Answer from Serge Ballesta on Stack Overflow
🌐
Pandas
pandas.pydata.org › pandas-docs › version › 0.25.3 › reference › api › pandas.core.window.Rolling.kurt.html
pandas.core.window.Rolling.kurt — pandas 0.25.3 documentation
The example below will show a rolling calculation with a window size of four matching the equivalent function call using scipy.stats. >>> arr = [1, 2, 3, 4, 999] >>> fmt = "{0:.6f}" # limit the printed precision to 6 digits >>> import scipy.stats >>> print(fmt.format(scipy.stats.kurtosis(arr[:-1], bias=False))) -1.200000 >>> print(fmt.format(scipy.stats.kurtosis(arr[1:], bias=False))) 3.999946 >>> s = pd.Series(arr) >>> s.rolling(4).kurt() 0 NaN 1 NaN 2 NaN 3 -1.200000 4 3.999946 dtype: float64
🌐
Pandas
pandas.pydata.org › pandas-docs › stable › reference › api › pandas.core.window.rolling.Rolling.kurt.html
pandas.core.window.rolling.Rolling.kurt — pandas 2.3.3 documentation
The example below will show a rolling calculation with a window size of four matching the equivalent function call using scipy.stats. >>> arr = [1, 2, 3, 4, 999] >>> import scipy.stats >>> print(f"{scipy.stats.kurtosis(arr[:-1], bias=False):.6f}") -1.200000 >>> print(f"{scipy.stats.kurtosis(arr[1:], bias=False):.6f}") 3.999946 >>> s = pd.Series(arr) >>> s.rolling(4).kurt() 0 NaN 1 NaN 2 NaN 3 -1.200000 4 3.999946 dtype: float64
🌐
Pandas
pandas.pydata.org › pandas-docs › version › 1.1 › reference › api › pandas.core.window.rolling.Rolling.kurt.html
pandas.core.window.rolling.Rolling.kurt — pandas 1.1.5 documentation
This function uses Fisher’s definition of kurtosis without bias. ... Under Review. ... Returned object type is determined by the caller of the rolling calculation.
🌐
W3cubDocs
docs.w3cub.com › pandas~0.25 › reference › api › pandas.core.window.rolling.kurt
Rolling.kurt() - Pandas 0.25 - W3cubDocs
>>> arr = [1, 2, 3, 4, 999] >>> fmt = "{0:.6f}" # limit the printed precision to 6 digits >>> import scipy.stats >>> print(fmt.format(scipy.stats.kurtosis(arr[:-1], bias=False))) -1.200000 >>> print(fmt.format(scipy.stats.kurtosis(arr[1:], bias=False))) 3.999946 >>> s = pd.Series(arr) >>> s.rolling(4).kurt() 0 NaN 1 NaN 2 NaN 3 -1.200000 4 3.999946 dtype: float64 · © 2008–2012, AQR Capital Management, LLC, Lambda Foundry, Inc. and PyData Development Team Licensed under the 3-clause BSD License. https://pandas.pydata.org/pandas-docs/version/0.25.0/reference/api/pandas.core.window.Rolling.kurt.html
Find elsewhere
🌐
Pandas
pandas.pydata.org › pandas-docs › version › 0.23.3 › generated › pandas.core.window.Rolling.kurt.html
pandas.core.window.Rolling.kurt — pandas 0.23.3 documentation
This function uses Fisher’s definition of kurtosis without bias. ... A minimum of 4 periods is required for the rolling calculation.
🌐
Pythontic
pythontic.com › pandas › dataframe-computations › kurtosis
kurtosis function in pandas | Pythontic.com
The pandas DataFrame has a computing method kurtosis() which computes the kurtosis for a set of values across a specific axis (i.e., a row or a column).
🌐
GitHub
github.com › pandas-dev › pandas › issues › 5749
Rolling skewness and kurtosis fail on a sample of all equal values · Issue #5749 · pandas-dev/pandas
December 19, 2013 - If one value occurs more times in a row than than the size of the window, the entire rolling computation fails, rather than just returning NaN for that one period (which is what I'd expect). For reference, scipy gives a kurtosis of -3 and a skewness of 0 (plus a warning) for this situation, which is not what I'd expect (since the higher moments are all zero, implying a division by zero).
Author: pandas-dev
🌐
GitHub
github.com › pandas-dev › pandas › issues › 18044
rolling skew and rolling kurt has wrong answer under all eq values · Issue #18044 · pandas-dev/pandas
October 31, 2017 - Code Sample, a copy-pastable example if possible pd.Series([1.1]*15).rolling(10).skew() pd.Series([1.1]*15).rolling(10).kurt() Problem description rolling skew() wrong result: pd.Series([1.1]*15).rolling(10).skew() 0 NaN 1 NaN 2 NaN 3 Na...
Author: pandas-dev
🌐
GitHub
github.com › ajcr › rolling › issues › 2
Implement rolling skew and rolling kurtosis methods · Issue #2 · ajcr/rolling
December 31, 2017 - pandas has implementations for rolling skew and rolling kurtosis. The implementations can be seen here.
Author: ajcr
🌐
Trading Strategy
tradingstrategy.ai › docs › api › technical-analysis › statistics › help › pandas_ta.statistics.kurtosis.html
kurtosis function in pandas_ta.statistics
API documentation for pandas_ta.statistics.kurtosis Python function. kurtosis(close, length=None, offset=None, **kwargs)[source]# Rolling Kurtosis · Sources: Calculation: Default Inputs: length=30 · KURTOSIS = close.rolling(length).kurt() Args: close (pd.Series): Series of ‘close’s length (int): It’s period.
🌐
GitHub
github.com › pandas-dev › pandas › issues › 58711
BUG: numerical inconsistency in calculating rolling kurtosis · Issue #58711 · pandas-dev/pandas
May 14, 2024 - import pandas as pd series_1 = pd.Series([-1] + ([1] * 19)) print(series_1.kurt()) print(series_1.rolling(20).kurt().max()) series_2 = pd.Series(([-1] * 7) + ([1] * 19)) print(series_2.rolling(20).kurt().max()) series_3 = pd.Series(([-1] * 6) + ([1] * 19)) print(series_3.rolling(20).kurt().max()) I met a problem in calculating rolling kurtosis for a specific kind of data.
Author: pandas-dev