Skip to content

Commit e017e58

Browse files
committed
Merge pull request #10986 from jreback/bn
TST: test_nanops turns off bottneck for all tests after
2 parents 2d0d58c + 2cf19d4 commit e017e58

File tree

7 files changed

+126
-127
lines changed

7 files changed

+126
-127
lines changed

pandas/stats/tests/test_moments.py

+57-86
Original file line numberDiff line numberDiff line change
@@ -842,6 +842,44 @@ def no_nans(x):
842842
_consistency_data = _create_consistency_data()
843843

844844
class TestMomentsConsistency(Base):
845+
base_functions = [
846+
(lambda v: Series(v).count(), None, 'count'),
847+
(lambda v: Series(v).max(), None, 'max'),
848+
(lambda v: Series(v).min(), None, 'min'),
849+
(lambda v: Series(v).sum(), None, 'sum'),
850+
(lambda v: Series(v).mean(), None, 'mean'),
851+
(lambda v: Series(v).std(), 1, 'std'),
852+
(lambda v: Series(v).cov(Series(v)), None, 'cov'),
853+
(lambda v: Series(v).corr(Series(v)), None, 'corr'),
854+
(lambda v: Series(v).var(), 1, 'var'),
855+
#(lambda v: Series(v).skew(), 3, 'skew'), # restore once GH 8086 is fixed
856+
#(lambda v: Series(v).kurt(), 4, 'kurt'), # restore once GH 8086 is fixed
857+
#(lambda x, min_periods: mom.expanding_quantile(x, 0.3, min_periods=min_periods, 'quantile'),
858+
# lambda v: Series(v).quantile(0.3), None, 'quantile'), # restore once GH 8084 is fixed
859+
(lambda v: Series(v).median(), None ,'median'),
860+
(np.nanmax, 1, 'max'),
861+
(np.nanmin, 1, 'min'),
862+
(np.nansum, 1, 'sum'),
863+
]
864+
if np.__version__ >= LooseVersion('1.8.0'):
865+
base_functions += [
866+
(np.nanmean, 1, 'mean'),
867+
(lambda v: np.nanstd(v, ddof=1), 1 ,'std'),
868+
(lambda v: np.nanvar(v, ddof=1), 1 ,'var'),
869+
]
870+
if np.__version__ >= LooseVersion('1.9.0'):
871+
base_functions += [
872+
(np.nanmedian, 1, 'median'),
873+
]
874+
no_nan_functions = [
875+
(np.max, None, 'max'),
876+
(np.min, None, 'min'),
877+
(np.sum, None, 'sum'),
878+
(np.mean, None, 'mean'),
879+
(lambda v: np.std(v, ddof=1), 1 ,'std'),
880+
(lambda v: np.var(v, ddof=1), 1 ,'var'),
881+
(np.median, None, 'median'),
882+
]
845883

846884
def _create_data(self):
847885
super(TestMomentsConsistency, self)._create_data()
@@ -877,9 +915,11 @@ def _non_null_values(x):
877915
# self.assertTrue(_non_null_values(corr_x_x).issubset(set([1.]))) # restore once rolling_cov(x, x) is identically equal to var(x)
878916

879917
if is_constant:
918+
exp = x.max() if isinstance(x, Series) else x.max().max()
919+
880920
# check mean of constant series
881921
expected = x * np.nan
882-
expected[count_x >= max(min_periods, 1)] = x.max().max()
922+
expected[count_x >= max(min_periods, 1)] = exp
883923
assert_equal(mean_x, expected)
884924

885925
# check correlation of constant series with itself is NaN
@@ -1030,44 +1070,6 @@ def _ewma(s, com, min_periods, adjust, ignore_na):
10301070

10311071
@slow
10321072
def test_expanding_consistency(self):
1033-
base_functions = [
1034-
(mom.expanding_count, lambda v: Series(v).count(), None),
1035-
(mom.expanding_max, lambda v: Series(v).max(), None),
1036-
(mom.expanding_min, lambda v: Series(v).min(), None),
1037-
(mom.expanding_sum, lambda v: Series(v).sum(), None),
1038-
(mom.expanding_mean, lambda v: Series(v).mean(), None),
1039-
(mom.expanding_std, lambda v: Series(v).std(), 1),
1040-
(mom.expanding_cov, lambda v: Series(v).cov(Series(v)), None),
1041-
(mom.expanding_corr, lambda v: Series(v).corr(Series(v)), None),
1042-
(mom.expanding_var, lambda v: Series(v).var(), 1),
1043-
#(mom.expanding_skew, lambda v: Series(v).skew(), 3), # restore once GH 8086 is fixed
1044-
#(mom.expanding_kurt, lambda v: Series(v).kurt(), 4), # restore once GH 8086 is fixed
1045-
#(lambda x, min_periods: mom.expanding_quantile(x, 0.3, min_periods=min_periods),
1046-
# lambda v: Series(v).quantile(0.3), None), # restore once GH 8084 is fixed
1047-
(mom.expanding_median, lambda v: Series(v).median(), None),
1048-
(mom.expanding_max, np.nanmax, 1),
1049-
(mom.expanding_min, np.nanmin, 1),
1050-
(mom.expanding_sum, np.nansum, 1),
1051-
]
1052-
if np.__version__ >= LooseVersion('1.8.0'):
1053-
base_functions += [
1054-
(mom.expanding_mean, np.nanmean, 1),
1055-
(mom.expanding_std, lambda v: np.nanstd(v, ddof=1), 1),
1056-
(mom.expanding_var, lambda v: np.nanvar(v, ddof=1), 1),
1057-
]
1058-
if np.__version__ >= LooseVersion('1.9.0'):
1059-
base_functions += [
1060-
(mom.expanding_median, np.nanmedian, 1),
1061-
]
1062-
no_nan_functions = [
1063-
(mom.expanding_max, np.max, None),
1064-
(mom.expanding_min, np.min, None),
1065-
(mom.expanding_sum, np.sum, None),
1066-
(mom.expanding_mean, np.mean, None),
1067-
(mom.expanding_std, lambda v: np.std(v, ddof=1), 1),
1068-
(mom.expanding_var, lambda v: np.var(v, ddof=1), 1),
1069-
(mom.expanding_median, np.median, None),
1070-
]
10711073

10721074
# suppress warnings about empty slices, as we are deliberately testing with empty/0-length Series/DataFrames
10731075
with warnings.catch_warnings():
@@ -1095,12 +1097,14 @@ def test_expanding_consistency(self):
10951097
# or (b) expanding_apply of np.nanxyz()
10961098
for (x, is_constant, no_nans) in self.data:
10971099
assert_equal = assert_series_equal if isinstance(x, Series) else assert_frame_equal
1098-
functions = base_functions
1100+
functions = self.base_functions
10991101

11001102
# GH 8269
11011103
if no_nans:
1102-
functions = base_functions + no_nan_functions
1103-
for (expanding_f, f, require_min_periods) in functions:
1104+
functions = self.base_functions + self.no_nan_functions
1105+
for (f, require_min_periods, name) in functions:
1106+
expanding_f = getattr(mom,'expanding_{0}'.format(name))
1107+
11041108
if require_min_periods and (min_periods is not None) and (min_periods < require_min_periods):
11051109
continue
11061110

@@ -1113,7 +1117,9 @@ def test_expanding_consistency(self):
11131117
else:
11141118
expanding_f_result = expanding_f(x, min_periods=min_periods)
11151119
expanding_apply_f_result = mom.expanding_apply(x, func=f, min_periods=min_periods)
1116-
assert_equal(expanding_f_result, expanding_apply_f_result)
1120+
1121+
if not tm._incompat_bottleneck_version(name):
1122+
assert_equal(expanding_f_result, expanding_apply_f_result)
11171123

11181124
if (expanding_f in [mom.expanding_cov, mom.expanding_corr]) and isinstance(x, DataFrame):
11191125
# test pairwise=True
@@ -1127,45 +1133,6 @@ def test_expanding_consistency(self):
11271133
@slow
11281134
def test_rolling_consistency(self):
11291135

1130-
base_functions = [
1131-
(mom.rolling_count, lambda v: Series(v).count(), None),
1132-
(mom.rolling_max, lambda v: Series(v).max(), None),
1133-
(mom.rolling_min, lambda v: Series(v).min(), None),
1134-
(mom.rolling_sum, lambda v: Series(v).sum(), None),
1135-
(mom.rolling_mean, lambda v: Series(v).mean(), None),
1136-
(mom.rolling_std, lambda v: Series(v).std(), 1),
1137-
(mom.rolling_cov, lambda v: Series(v).cov(Series(v)), None),
1138-
(mom.rolling_corr, lambda v: Series(v).corr(Series(v)), None),
1139-
(mom.rolling_var, lambda v: Series(v).var(), 1),
1140-
#(mom.rolling_skew, lambda v: Series(v).skew(), 3), # restore once GH 8086 is fixed
1141-
#(mom.rolling_kurt, lambda v: Series(v).kurt(), 4), # restore once GH 8086 is fixed
1142-
#(lambda x, window, min_periods, center: mom.rolling_quantile(x, window, 0.3, min_periods=min_periods, center=center),
1143-
# lambda v: Series(v).quantile(0.3), None), # restore once GH 8084 is fixed
1144-
(mom.rolling_median, lambda v: Series(v).median(), None),
1145-
(mom.rolling_max, np.nanmax, 1),
1146-
(mom.rolling_min, np.nanmin, 1),
1147-
(mom.rolling_sum, np.nansum, 1),
1148-
]
1149-
if np.__version__ >= LooseVersion('1.8.0'):
1150-
base_functions += [
1151-
(mom.rolling_mean, np.nanmean, 1),
1152-
(mom.rolling_std, lambda v: np.nanstd(v, ddof=1), 1),
1153-
(mom.rolling_var, lambda v: np.nanvar(v, ddof=1), 1),
1154-
]
1155-
if np.__version__ >= LooseVersion('1.9.0'):
1156-
base_functions += [
1157-
(mom.rolling_median, np.nanmedian, 1),
1158-
]
1159-
no_nan_functions = [
1160-
(mom.rolling_max, np.max, None),
1161-
(mom.rolling_min, np.min, None),
1162-
(mom.rolling_sum, np.sum, None),
1163-
(mom.rolling_mean, np.mean, None),
1164-
(mom.rolling_std, lambda v: np.std(v, ddof=1), 1),
1165-
(mom.rolling_var, lambda v: np.var(v, ddof=1), 1),
1166-
(mom.rolling_median, np.median, None),
1167-
]
1168-
11691136
for window in [1, 2, 3, 10, 20]:
11701137
for min_periods in set([0, 1, 2, 3, 4, window]):
11711138
if min_periods and (min_periods > window):
@@ -1195,11 +1162,14 @@ def test_rolling_consistency(self):
11951162
for (x, is_constant, no_nans) in self.data:
11961163

11971164
assert_equal = assert_series_equal if isinstance(x, Series) else assert_frame_equal
1198-
functions = base_functions
1165+
functions = self.base_functions
1166+
11991167
# GH 8269
12001168
if no_nans:
1201-
functions = base_functions + no_nan_functions
1202-
for (rolling_f, f, require_min_periods) in functions:
1169+
functions = self.base_functions + self.no_nan_functions
1170+
for (f, require_min_periods, name) in functions:
1171+
rolling_f = getattr(mom,'rolling_{0}'.format(name))
1172+
12031173
if require_min_periods and (min_periods is not None) and (min_periods < require_min_periods):
12041174
continue
12051175

@@ -1214,7 +1184,8 @@ def test_rolling_consistency(self):
12141184
rolling_f_result = rolling_f(x, window=window, min_periods=min_periods, center=center)
12151185
rolling_apply_f_result = mom.rolling_apply(x, window=window, func=f,
12161186
min_periods=min_periods, center=center)
1217-
assert_equal(rolling_f_result, rolling_apply_f_result)
1187+
if not tm._incompat_bottleneck_version(name):
1188+
assert_equal(rolling_f_result, rolling_apply_f_result)
12181189

12191190
if (rolling_f in [mom.rolling_cov, mom.rolling_corr]) and isinstance(x, DataFrame):
12201191
# test pairwise=True

pandas/tests/test_frame.py

+10-6
Original file line numberDiff line numberDiff line change
@@ -12471,7 +12471,9 @@ def test_stat_operators_attempt_obj_array(self):
1247112471
self.assertEqual(df.values.dtype, np.object_)
1247212472
result = getattr(df, meth)(1)
1247312473
expected = getattr(df.astype('f8'), meth)(1)
12474-
assert_series_equal(result, expected)
12474+
12475+
if not tm._incompat_bottleneck_version(meth):
12476+
assert_series_equal(result, expected)
1247512477

1247612478
def test_mean(self):
1247712479
self._check_stat_op('mean', np.mean, check_dates=True)
@@ -12694,9 +12696,10 @@ def wrapper(x):
1269412696
assert_series_equal(result0, frame.apply(skipna_wrapper),
1269512697
check_dtype=check_dtype,
1269612698
check_less_precise=check_less_precise)
12697-
assert_series_equal(result1, frame.apply(skipna_wrapper, axis=1),
12698-
check_dtype=False,
12699-
check_less_precise=check_less_precise)
12699+
if not tm._incompat_bottleneck_version(name):
12700+
assert_series_equal(result1, frame.apply(skipna_wrapper, axis=1),
12701+
check_dtype=False,
12702+
check_less_precise=check_less_precise)
1270012703

1270112704
# check dtypes
1270212705
if check_dtype:
@@ -12725,8 +12728,9 @@ def wrapper(x):
1272512728
all_na = self.frame * np.NaN
1272612729
r0 = getattr(all_na, name)(axis=0)
1272712730
r1 = getattr(all_na, name)(axis=1)
12728-
self.assertTrue(np.isnan(r0).all())
12729-
self.assertTrue(np.isnan(r1).all())
12731+
if not tm._incompat_bottleneck_version(name):
12732+
self.assertTrue(np.isnan(r0).all())
12733+
self.assertTrue(np.isnan(r1).all())
1273012734

1273112735
def test_mode(self):
1273212736
df = pd.DataFrame({"A": [12, 12, 11, 12, 19, 11],

pandas/tests/test_groupby.py

+17-13
Original file line numberDiff line numberDiff line change
@@ -2014,7 +2014,10 @@ def test_cythonized_aggers(self):
20142014
df = DataFrame(data)
20152015
df.loc[2:10:2,'C'] = nan
20162016

2017-
def _testit(op):
2017+
def _testit(name):
2018+
2019+
op = lambda x: getattr(x,name)()
2020+
20182021
# single column
20192022
grouped = df.drop(['B'], axis=1).groupby('A')
20202023
exp = {}
@@ -2035,18 +2038,19 @@ def _testit(op):
20352038
exp.name = 'C'
20362039

20372040
result = op(grouped)['C']
2038-
assert_series_equal(result, exp)
2039-
2040-
_testit(lambda x: x.count())
2041-
_testit(lambda x: x.sum())
2042-
_testit(lambda x: x.std())
2043-
_testit(lambda x: x.var())
2044-
_testit(lambda x: x.sem())
2045-
_testit(lambda x: x.mean())
2046-
_testit(lambda x: x.median())
2047-
_testit(lambda x: x.prod())
2048-
_testit(lambda x: x.min())
2049-
_testit(lambda x: x.max())
2041+
if not tm._incompat_bottleneck_version(name):
2042+
assert_series_equal(result, exp)
2043+
2044+
_testit('count')
2045+
_testit('sum')
2046+
_testit('std')
2047+
_testit('var')
2048+
_testit('sem')
2049+
_testit('mean')
2050+
_testit('median')
2051+
_testit('prod')
2052+
_testit('min')
2053+
_testit('max')
20502054

20512055
def test_max_min_non_numeric(self):
20522056
# #2700

pandas/tests/test_nanops.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@
99
import pandas.core.nanops as nanops
1010
import pandas.util.testing as tm
1111

12-
nanops._USE_BOTTLENECK = False
13-
12+
use_bn = nanops._USE_BOTTLENECK
1413

1514
class TestnanopsDataFrame(tm.TestCase):
15+
1616
def setUp(self):
1717
np.random.seed(11235)
18+
nanops._USE_BOTTLENECK = False
1819

1920
self.arr_shape = (11, 7, 5)
2021

@@ -116,6 +117,9 @@ def setUp(self):
116117
self.arr_float_nan_inf_1d = self.arr_float_nan_inf[:, 0, 0]
117118
self.arr_nan_nan_inf_1d = self.arr_nan_nan_inf[:, 0, 0]
118119

120+
def tearDown(self):
121+
nanops._USE_BOTTLENECK = use_bn
122+
119123
def check_results(self, targ, res, axis):
120124
res = getattr(res, 'asm8', res)
121125
res = getattr(res, 'values', res)

pandas/tests/test_panel.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,8 @@ def wrapper(x):
168168

169169
for i in range(obj.ndim):
170170
result = f(axis=i)
171-
assert_frame_equal(result, obj.apply(skipna_wrapper, axis=i))
171+
if not tm._incompat_bottleneck_version(name):
172+
assert_frame_equal(result, obj.apply(skipna_wrapper, axis=i))
172173

173174
self.assertRaises(Exception, f, axis=obj.ndim)
174175

pandas/tests/test_panel4d.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,8 @@ def wrapper(x):
144144

145145
for i in range(obj.ndim):
146146
result = f(axis=i)
147-
assert_panel_equal(result, obj.apply(skipna_wrapper, axis=i))
147+
if not tm._incompat_bottleneck_version(name):
148+
assert_panel_equal(result, obj.apply(skipna_wrapper, axis=i))
148149

149150
self.assertRaises(Exception, f, axis=obj.ndim)
150151

pandas/util/testing.py

+32-18
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,38 @@ def _skip_if_python26():
246246
import nose
247247
raise nose.SkipTest("skipping on python2.6")
248248

249+
def _incompat_bottleneck_version(method):
250+
""" skip if we have bottleneck installed
251+
and its >= 1.0
252+
as we don't match the nansum/nanprod behavior for all-nan
253+
ops, see GH9422
254+
"""
255+
if method not in ['sum','prod']:
256+
return False
257+
try:
258+
import bottleneck as bn
259+
return bn.__version__ >= LooseVersion('1.0')
260+
except ImportError:
261+
return False
262+
263+
def skip_if_no_ne(engine='numexpr'):
264+
import nose
265+
_USE_NUMEXPR = pd.computation.expressions._USE_NUMEXPR
266+
267+
if engine == 'numexpr':
268+
try:
269+
import numexpr as ne
270+
except ImportError:
271+
raise nose.SkipTest("numexpr not installed")
272+
273+
if not _USE_NUMEXPR:
274+
raise nose.SkipTest("numexpr disabled")
275+
276+
if ne.__version__ < LooseVersion('2.0'):
277+
raise nose.SkipTest("numexpr version too low: "
278+
"%s" % ne.__version__)
279+
280+
249281

250282
#------------------------------------------------------------------------------
251283
# locale utilities
@@ -1986,24 +2018,6 @@ def assert_produces_warning(expected_warning=Warning, filter_level="always",
19862018
% extra_warnings)
19872019

19882020

1989-
def skip_if_no_ne(engine='numexpr'):
1990-
import nose
1991-
_USE_NUMEXPR = pd.computation.expressions._USE_NUMEXPR
1992-
1993-
if engine == 'numexpr':
1994-
try:
1995-
import numexpr as ne
1996-
except ImportError:
1997-
raise nose.SkipTest("numexpr not installed")
1998-
1999-
if not _USE_NUMEXPR:
2000-
raise nose.SkipTest("numexpr disabled")
2001-
2002-
if ne.__version__ < LooseVersion('2.0'):
2003-
raise nose.SkipTest("numexpr version too low: "
2004-
"%s" % ne.__version__)
2005-
2006-
20072021
def disabled(t):
20082022
t.disabled = True
20092023
return t

0 commit comments

Comments
 (0)