2
2
datetime ,
3
3
timedelta ,
4
4
)
5
- import platform
6
- import sys
7
5
8
6
import numpy as np
9
7
import pytest
@@ -1083,14 +1081,9 @@ def test_rolling_sem(frame_or_series):
1083
1081
tm .assert_series_equal (result , expected )
1084
1082
1085
1083
1086
- @pytest .mark .skipif (
1087
- is_platform_arm ()
1088
- or is_platform_power ()
1089
- or is_platform_riscv64 ()
1090
- or platform .architecture ()[0 ] == "32bit"
1091
- or sys .platform in ("emscripten" , "wasm" ),
1092
- reason = "GH 38921: skipped due to known numerical instability on 32-bit or "
1093
- "WebAssembly platforms (Pyodide)" ,
1084
+ @pytest .mark .xfail (
1085
+ is_platform_arm () or is_platform_power () or is_platform_riscv64 (),
1086
+ reason = "GH 38921" ,
1094
1087
)
1095
1088
@pytest .mark .parametrize (
1096
1089
("func" , "third_value" , "values" ),
@@ -1106,7 +1099,10 @@ def test_rolling_var_numerical_issues(func, third_value, values):
1106
1099
ds = Series ([99999999999999999 , 1 , third_value , 2 , 3 , 1 , 1 ])
1107
1100
result = getattr (ds .rolling (2 ), func )()
1108
1101
expected = Series ([np .nan ] + values )
1109
- tm .assert_almost_equal (result [1 :].values , expected [1 :].values , rtol = 1e-3 , atol = 1e-6 )
1102
+ tm .assert_series_equal (result , expected )
1103
+ # GH 42064
1104
+ # new `roll_var` will output 0.0 correctly
1105
+ tm .assert_series_equal (result == 0 , expected == 0 )
1110
1106
1111
1107
1112
1108
def test_timeoffset_as_window_parameter_for_corr (unit ):
@@ -1950,3 +1946,66 @@ def test_rolling_timedelta_window_non_nanoseconds(unit, tz):
1950
1946
df .index = df .index .as_unit ("ns" )
1951
1947
1952
1948
tm .assert_frame_equal (ref_df , df )
1949
+
1950
+
1951
+ class PrescribedWindowIndexer (BaseIndexer ):
1952
+ def __init__ (self , start , end ):
1953
+ self ._start = start
1954
+ self ._end = end
1955
+ super ().__init__ ()
1956
+
1957
+ def get_window_bounds (
1958
+ self , num_values = None , min_periods = None , center = None , closed = None , step = None
1959
+ ):
1960
+ if num_values is None :
1961
+ num_values = len (self ._start )
1962
+ start = np .clip (self ._start , 0 , num_values )
1963
+ end = np .clip (self ._end , 0 , num_values )
1964
+ return start , end
1965
+
1966
+
1967
+ class TestMinMax :
1968
+ @pytest .mark .parametrize (
1969
+ "is_max, has_nan, exp_list" ,
1970
+ [
1971
+ (True , False , [3.0 , 5.0 , 2.0 , 5.0 , 1.0 , 5.0 , 6.0 , 7.0 , 8.0 , 9.0 ]),
1972
+ (True , True , [3.0 , 4.0 , 2.0 , 4.0 , 1.0 , 4.0 , 6.0 , 7.0 , 7.0 , 9.0 ]),
1973
+ (False , False , [3.0 , 2.0 , 2.0 , 1.0 , 1.0 , 0.0 , 0.0 , 0.0 , 7.0 , 0.0 ]),
1974
+ (False , True , [3.0 , 2.0 , 2.0 , 1.0 , 1.0 , 1.0 , 6.0 , 6.0 , 7.0 , 1.0 ]),
1975
+ ],
1976
+ )
1977
+ def test_minmax (self , is_max , has_nan , exp_list ):
1978
+ nan_idx = [0 , 5 , 8 ]
1979
+ df = DataFrame (
1980
+ {
1981
+ "data" : [5.0 , 4.0 , 3.0 , 2.0 , 1.0 , 0.0 , 6.0 , 7.0 , 8.0 , 9.0 ],
1982
+ "start" : [2 , 0 , 3 , 0 , 4 , 0 , 5 , 5 , 7 , 3 ],
1983
+ "end" : [3 , 4 , 4 , 5 , 5 , 6 , 7 , 8 , 9 , 10 ],
1984
+ }
1985
+ )
1986
+ if has_nan :
1987
+ df .loc [nan_idx , "data" ] = np .nan
1988
+ expected = Series (exp_list , name = "data" )
1989
+ r = df .data .rolling (
1990
+ PrescribedWindowIndexer (df .start .to_numpy (), df .end .to_numpy ())
1991
+ )
1992
+ if is_max :
1993
+ result = r .max ()
1994
+ else :
1995
+ result = r .min ()
1996
+
1997
+ tm .assert_series_equal (result , expected )
1998
+
1999
+ def test_wrong_order (self ):
2000
+ start = np .array (range (5 ), dtype = np .int64 )
2001
+ end = start + 1
2002
+ end [3 ] = end [2 ]
2003
+ start [3 ] = start [2 ] - 1
2004
+
2005
+ df = DataFrame ({"data" : start * 1.0 , "start" : start , "end" : end })
2006
+
2007
+ r = df .data .rolling (PrescribedWindowIndexer (start , end ))
2008
+ with pytest .raises (
2009
+ ValueError , match = "Start/End ordering requirement is violated at index 3"
2010
+ ):
2011
+ r .max ()
0 commit comments