Skip to content

Commit 6f26fee

Browse files
charlesdong1991rhshadrach
authored andcommitted
TST: Clean moments consistency (pandas-dev#33813)
1 parent 1a9de7c commit 6f26fee

File tree

4 files changed

+314
-136
lines changed

4 files changed

+314
-136
lines changed

pandas/tests/window/common.py

+85-70
Original file line numberDiff line numberDiff line change
@@ -252,43 +252,15 @@ def _test_moments_consistency_var_debiasing_factors(
252252
var_debiasing_factors_x = var_debiasing_factors(x)
253253
tm.assert_equal(var_unbiased_x, var_biased_x * var_debiasing_factors_x)
254254

255-
def _test_moments_consistency(
256-
self,
257-
min_periods,
258-
count,
259-
mean,
260-
corr,
261-
var_unbiased=None,
262-
std_unbiased=None,
263-
cov_unbiased=None,
264-
var_biased=None,
265-
std_biased=None,
266-
cov_biased=None,
255+
def _test_moments_consistency_var_data(
256+
self, min_periods, count, mean, var_unbiased, var_biased
267257
):
268-
269258
for (x, is_constant, no_nans) in self.data:
270259
count_x = count(x)
271260
mean_x = mean(x)
272-
273-
for (std, var, cov) in [
274-
(std_biased, var_biased, cov_biased),
275-
(std_unbiased, var_unbiased, cov_unbiased),
276-
]:
277-
278-
# check that var(x), std(x), and cov(x) are all >= 0
261+
for var in [var_biased, var_unbiased]:
279262
var_x = var(x)
280-
std_x = std(x)
281263
assert not (var_x < 0).any().any()
282-
assert not (std_x < 0).any().any()
283-
if cov:
284-
cov_x_x = cov(x, x)
285-
assert not (cov_x_x < 0).any().any()
286-
287-
# check that var(x) == cov(x, x)
288-
tm.assert_equal(var_x, cov_x_x)
289-
290-
# check that var(x) == std(x)^2
291-
tm.assert_equal(var_x, std_x * std_x)
292264

293265
if var is var_biased:
294266
# check that biased var(x) == mean(x^2) - mean(x)^2
@@ -304,45 +276,88 @@ def _test_moments_consistency(
304276
expected[count_x < 2] = np.nan
305277
tm.assert_equal(var_x, expected)
306278

307-
if isinstance(x, Series):
308-
for (y, is_constant, no_nans) in self.data:
309-
if not x.isna().equals(y.isna()):
310-
# can only easily test two Series with similar
311-
# structure
312-
continue
313-
314-
# check that cor(x, y) is symmetric
315-
corr_x_y = corr(x, y)
316-
corr_y_x = corr(y, x)
317-
tm.assert_equal(corr_x_y, corr_y_x)
318-
319-
if cov:
320-
# check that cov(x, y) is symmetric
321-
cov_x_y = cov(x, y)
322-
cov_y_x = cov(y, x)
323-
tm.assert_equal(cov_x_y, cov_y_x)
324-
325-
# check that cov(x, y) == (var(x+y) - var(x) -
326-
# var(y)) / 2
327-
var_x_plus_y = var(x + y)
328-
var_y = var(y)
329-
tm.assert_equal(
330-
cov_x_y, 0.5 * (var_x_plus_y - var_x - var_y)
331-
)
332-
333-
# check that corr(x, y) == cov(x, y) / (std(x) *
334-
# std(y))
335-
std_y = std(y)
336-
tm.assert_equal(corr_x_y, cov_x_y / (std_x * std_y))
337-
338-
if cov is cov_biased:
339-
# check that biased cov(x, y) == mean(x*y) -
340-
# mean(x)*mean(y)
341-
mean_y = mean(y)
342-
mean_x_times_y = mean(x * y)
343-
tm.assert_equal(
344-
cov_x_y, mean_x_times_y - (mean_x * mean_y)
345-
)
279+
def _test_moments_consistency_std_data(
280+
self, std_unbiased, var_unbiased, std_biased, var_biased
281+
):
282+
for (x, is_constant, no_nans) in self.data:
283+
for (std, var) in [(std_biased, var_biased), (std_unbiased, var_unbiased)]:
284+
var_x = var(x)
285+
std_x = std(x)
286+
assert not (var_x < 0).any().any()
287+
assert not (std_x < 0).any().any()
288+
289+
# check that var(x) == std(x)^2
290+
tm.assert_equal(var_x, std_x * std_x)
291+
292+
def _test_moments_consistency_cov_data(
293+
self, cov_unbiased, var_unbiased, cov_biased, var_biased
294+
):
295+
for (x, is_constant, no_nans) in self.data:
296+
for (cov, var) in [(cov_biased, var_biased), (cov_unbiased, var_unbiased)]:
297+
var_x = var(x)
298+
assert not (var_x < 0).any().any()
299+
if cov:
300+
cov_x_x = cov(x, x)
301+
assert not (cov_x_x < 0).any().any()
302+
303+
# check that var(x) == cov(x, x)
304+
tm.assert_equal(var_x, cov_x_x)
305+
306+
def _test_moments_consistency_series_data(
307+
self,
308+
corr,
309+
mean,
310+
std_biased,
311+
std_unbiased,
312+
cov_unbiased,
313+
var_unbiased,
314+
var_biased,
315+
cov_biased,
316+
):
317+
for (x, is_constant, no_nans) in self.data:
318+
if isinstance(x, Series):
319+
y = x
320+
mean_x = mean(x)
321+
if not x.isna().equals(y.isna()):
322+
# can only easily test two Series with similar
323+
# structure
324+
pass
325+
326+
# check that cor(x, y) is symmetric
327+
corr_x_y = corr(x, y)
328+
corr_y_x = corr(y, x)
329+
tm.assert_equal(corr_x_y, corr_y_x)
330+
331+
for (std, var, cov) in [
332+
(std_biased, var_biased, cov_biased),
333+
(std_unbiased, var_unbiased, cov_unbiased),
334+
]:
335+
var_x = var(x)
336+
std_x = std(x)
337+
338+
if cov:
339+
# check that cov(x, y) is symmetric
340+
cov_x_y = cov(x, y)
341+
cov_y_x = cov(y, x)
342+
tm.assert_equal(cov_x_y, cov_y_x)
343+
344+
# check that cov(x, y) == (var(x+y) - var(x) -
345+
# var(y)) / 2
346+
var_x_plus_y = var(x + y)
347+
var_y = var(y)
348+
tm.assert_equal(cov_x_y, 0.5 * (var_x_plus_y - var_x - var_y))
349+
350+
# check that corr(x, y) == cov(x, y) / (std(x) *
351+
# std(y))
352+
std_y = std(y)
353+
tm.assert_equal(corr_x_y, cov_x_y / (std_x * std_y))
354+
355+
if cov is cov_biased:
356+
# check that biased cov(x, y) == mean(x*y) -
357+
# mean(x)*mean(y)
358+
mean_y = mean(y)
359+
mean_x_times_y = mean(x * y)
360+
tm.assert_equal(cov_x_y, mean_x_times_y - (mean_x * mean_y))
346361

347362
def _check_pairwise_moment(self, dispatch, name, **kwargs):
348363
def get_result(obj, obj2=None):

pandas/tests/window/moments/test_moments_ewm.py

+83-3
Original file line numberDiff line numberDiff line change
@@ -398,10 +398,90 @@ def _ewma(s, com, min_periods, adjust, ignore_na):
398398
)
399399
),
400400
)
401-
# test consistency between different ewm* moments
402-
self._test_moments_consistency(
403-
min_periods=min_periods,
401+
402+
@pytest.mark.parametrize("min_periods", [0, 1, 2, 3, 4])
403+
@pytest.mark.parametrize("adjust", [True, False])
404+
@pytest.mark.parametrize("ignore_na", [True, False])
405+
def test_ewm_consistency_var(self, min_periods, adjust, ignore_na):
406+
com = 3.0
407+
self._test_moments_consistency_var_data(
408+
min_periods,
404409
count=lambda x: x.expanding().count(),
410+
mean=lambda x: x.ewm(
411+
com=com, min_periods=min_periods, adjust=adjust, ignore_na=ignore_na
412+
).mean(),
413+
var_unbiased=lambda x: (
414+
x.ewm(
415+
com=com, min_periods=min_periods, adjust=adjust, ignore_na=ignore_na
416+
).var(bias=False)
417+
),
418+
var_biased=lambda x: (
419+
x.ewm(
420+
com=com, min_periods=min_periods, adjust=adjust, ignore_na=ignore_na
421+
).var(bias=True)
422+
),
423+
)
424+
425+
@pytest.mark.parametrize("min_periods", [0, 1, 2, 3, 4])
426+
@pytest.mark.parametrize("adjust", [True, False])
427+
@pytest.mark.parametrize("ignore_na", [True, False])
428+
def test_ewm_consistency_std(self, min_periods, adjust, ignore_na):
429+
com = 3.0
430+
self._test_moments_consistency_std_data(
431+
var_unbiased=lambda x: (
432+
x.ewm(
433+
com=com, min_periods=min_periods, adjust=adjust, ignore_na=ignore_na
434+
).var(bias=False)
435+
),
436+
std_unbiased=lambda x: (
437+
x.ewm(
438+
com=com, min_periods=min_periods, adjust=adjust, ignore_na=ignore_na
439+
).std(bias=False)
440+
),
441+
var_biased=lambda x: (
442+
x.ewm(
443+
com=com, min_periods=min_periods, adjust=adjust, ignore_na=ignore_na
444+
).var(bias=True)
445+
),
446+
std_biased=lambda x: x.ewm(
447+
com=com, min_periods=min_periods, adjust=adjust, ignore_na=ignore_na
448+
).std(bias=True),
449+
)
450+
451+
@pytest.mark.parametrize("min_periods", [0, 1, 2, 3, 4])
452+
@pytest.mark.parametrize("adjust", [True, False])
453+
@pytest.mark.parametrize("ignore_na", [True, False])
454+
def test_ewm_consistency_cov(self, min_periods, adjust, ignore_na):
455+
com = 3.0
456+
self._test_moments_consistency_cov_data(
457+
var_unbiased=lambda x: (
458+
x.ewm(
459+
com=com, min_periods=min_periods, adjust=adjust, ignore_na=ignore_na
460+
).var(bias=False)
461+
),
462+
cov_unbiased=lambda x, y: (
463+
x.ewm(
464+
com=com, min_periods=min_periods, adjust=adjust, ignore_na=ignore_na
465+
).cov(y, bias=False)
466+
),
467+
var_biased=lambda x: (
468+
x.ewm(
469+
com=com, min_periods=min_periods, adjust=adjust, ignore_na=ignore_na
470+
).var(bias=True)
471+
),
472+
cov_biased=lambda x, y: (
473+
x.ewm(
474+
com=com, min_periods=min_periods, adjust=adjust, ignore_na=ignore_na
475+
).cov(y, bias=True)
476+
),
477+
)
478+
479+
@pytest.mark.parametrize("min_periods", [0, 1, 2, 3, 4])
480+
@pytest.mark.parametrize("adjust", [True, False])
481+
@pytest.mark.parametrize("ignore_na", [True, False])
482+
def test_ewm_consistency_series_data(self, min_periods, adjust, ignore_na):
483+
com = 3.0
484+
self._test_moments_consistency_series_data(
405485
mean=lambda x: x.ewm(
406486
com=com, min_periods=min_periods, adjust=adjust, ignore_na=ignore_na
407487
).mean(),

pandas/tests/window/moments/test_moments_expanding.py

+41-14
Original file line numberDiff line numberDiff line change
@@ -367,20 +367,6 @@ def test_expanding_consistency(self, min_periods):
367367
/ (x.expanding().count() - 1.0).replace(0.0, np.nan)
368368
),
369369
)
370-
self._test_moments_consistency(
371-
min_periods=min_periods,
372-
count=lambda x: x.expanding(min_periods=min_periods).count(),
373-
mean=lambda x: x.expanding(min_periods=min_periods).mean(),
374-
corr=lambda x, y: x.expanding(min_periods=min_periods).corr(y),
375-
var_unbiased=lambda x: x.expanding(min_periods=min_periods).var(),
376-
std_unbiased=lambda x: x.expanding(min_periods=min_periods).std(),
377-
cov_unbiased=lambda x, y: x.expanding(min_periods=min_periods).cov(y),
378-
var_biased=lambda x: x.expanding(min_periods=min_periods).var(ddof=0),
379-
std_biased=lambda x: x.expanding(min_periods=min_periods).std(ddof=0),
380-
cov_biased=lambda x, y: x.expanding(min_periods=min_periods).cov(
381-
y, ddof=0
382-
),
383-
)
384370

385371
# test consistency between expanding_xyz() and either (a)
386372
# expanding_apply of Series.xyz(), or (b) expanding_apply of
@@ -418,3 +404,44 @@ def test_expanding_consistency(self, min_periods):
418404
# GH 9422
419405
if name in ["sum", "prod"]:
420406
tm.assert_equal(expanding_f_result, expanding_apply_f_result)
407+
408+
@pytest.mark.parametrize("min_periods", [0, 1, 2, 3, 4])
409+
def test_moments_consistency_var(self, min_periods):
410+
self._test_moments_consistency_var_data(
411+
min_periods=min_periods,
412+
count=lambda x: x.expanding(min_periods=min_periods).count(),
413+
mean=lambda x: x.expanding(min_periods=min_periods).mean(),
414+
var_unbiased=lambda x: x.expanding(min_periods=min_periods).var(),
415+
var_biased=lambda x: x.expanding(min_periods=min_periods).var(ddof=0),
416+
)
417+
418+
@pytest.mark.parametrize("min_periods", [0, 1, 2, 3, 4])
419+
def test_expanding_consistency_std(self, min_periods):
420+
self._test_moments_consistency_std_data(
421+
var_unbiased=lambda x: x.expanding(min_periods=min_periods).var(),
422+
std_unbiased=lambda x: x.expanding(min_periods=min_periods).std(),
423+
var_biased=lambda x: x.expanding(min_periods=min_periods).var(ddof=0),
424+
std_biased=lambda x: x.expanding(min_periods=min_periods).std(ddof=0),
425+
)
426+
427+
@pytest.mark.parametrize("min_periods", [0, 1, 2, 3, 4])
428+
def test_expanding_consistency_cov(self, min_periods):
429+
self._test_moments_consistency_cov_data(
430+
var_unbiased=lambda x: x.expanding(min_periods=min_periods).var(),
431+
cov_unbiased=lambda x, y: x.expanding(min_periods=min_periods).cov(y),
432+
var_biased=lambda x: x.expanding(min_periods=min_periods).var(ddof=0),
433+
cov_biased=lambda x, y: x.expanding(min_periods=min_periods).cov(y, ddof=0),
434+
)
435+
436+
@pytest.mark.parametrize("min_periods", [0, 1, 2, 3, 4])
437+
def test_expanding_consistency_series(self, min_periods):
438+
self._test_moments_consistency_series_data(
439+
mean=lambda x: x.expanding(min_periods=min_periods).mean(),
440+
corr=lambda x, y: x.expanding(min_periods=min_periods).corr(y),
441+
var_unbiased=lambda x: x.expanding(min_periods=min_periods).var(),
442+
std_unbiased=lambda x: x.expanding(min_periods=min_periods).std(),
443+
cov_unbiased=lambda x, y: x.expanding(min_periods=min_periods).cov(y),
444+
var_biased=lambda x: x.expanding(min_periods=min_periods).var(ddof=0),
445+
std_biased=lambda x: x.expanding(min_periods=min_periods).std(ddof=0),
446+
cov_biased=lambda x, y: x.expanding(min_periods=min_periods).cov(y, ddof=0),
447+
)

0 commit comments

Comments
 (0)