@@ -190,7 +190,7 @@ def check_fun_data(self, testfunc, targfunc,
190
190
if skipna and axis is None :
191
191
res = testfunc (testarval , ** kwargs )
192
192
self .check_results (targ , res , axis )
193
- except AssertionError as exc :
193
+ except BaseException as exc :
194
194
exc .args += ('axis: %s of %s' % (axis , testarval .ndim - 1 ),
195
195
'skipna: %s' % skipna ,
196
196
'kwargs: %s' % kwargs )
@@ -222,7 +222,7 @@ def check_fun(self, testfunc, targfunc,
222
222
try :
223
223
self .check_fun_data (testfunc , targfunc ,
224
224
testarval , targarval , targarnanval , ** kwargs )
225
- except AssertionError as exc :
225
+ except BaseException as exc :
226
226
exc .args += ('testar: %s' % testar ,
227
227
'targar: %s' % targar ,
228
228
'targarnan: %s' % targarnan )
@@ -295,7 +295,7 @@ def check_funs_ddof(self, testfunc, targfunc,
295
295
allow_complex , allow_all_nan , allow_str ,
296
296
allow_date , allow_tdelta , allow_obj ,
297
297
ddof = ddof )
298
- except AssertionError as exc :
298
+ except BaseException as exc :
299
299
exc .args += ('ddof %s' % ddof ,)
300
300
raise
301
301
@@ -370,7 +370,7 @@ def test_nanvar(self):
370
370
allow_complex = False ,
371
371
allow_str = False ,
372
372
allow_date = False ,
373
- allow_tdelta = False ,
373
+ allow_tdelta = True ,
374
374
allow_obj = 'convert' )
375
375
376
376
def test_nanstd (self ):
@@ -388,7 +388,8 @@ def test_nansem(self):
388
388
allow_complex = False ,
389
389
allow_str = False ,
390
390
allow_date = False ,
391
- allow_tdelta = False )
391
+ allow_tdelta = True ,
392
+ allow_obj = 'convert' )
392
393
393
394
def _minmax_wrap (self , value , axis = None , func = None ):
394
395
res = func (value , axis )
@@ -676,7 +677,7 @@ def check_bool(self, func, value, correct, *args, **kwargs):
676
677
self .assertTrue (res0 )
677
678
else :
678
679
self .assertFalse (res0 )
679
- except AssertionError as exc :
680
+ except BaseException as exc :
680
681
exc .args += ('dim: %s' % getattr (value , 'ndim' , value ),)
681
682
raise
682
683
if not hasattr (value , 'ndim' ):
@@ -713,7 +714,7 @@ def test__has_infs(self):
713
714
val = getattr (self , arr )
714
715
try :
715
716
self .check_bool (nanops ._has_infs , val , correct )
716
- except AssertionError as exc :
717
+ except BaseException as exc :
717
718
exc .args += (arr ,)
718
719
raise
719
720
@@ -723,7 +724,7 @@ def test__has_infs(self):
723
724
self .check_bool (nanops ._has_infs , val , correct )
724
725
self .check_bool (nanops ._has_infs , val .astype ('f4' ), correct )
725
726
self .check_bool (nanops ._has_infs , val .astype ('f2' ), correct )
726
- except AssertionError as exc :
727
+ except BaseException as exc :
727
728
exc .args += (arr ,)
728
729
raise
729
730
@@ -756,7 +757,7 @@ def test__isfinite(self):
756
757
val = getattr (self , arr )
757
758
try :
758
759
self .check_bool (func1 , val , correct )
759
- except AssertionError as exc :
760
+ except BaseException as exc :
760
761
exc .args += (arr ,)
761
762
raise
762
763
@@ -766,7 +767,7 @@ def test__isfinite(self):
766
767
self .check_bool (func1 , val , correct )
767
768
self .check_bool (func1 , val .astype ('f4' ), correct )
768
769
self .check_bool (func1 , val .astype ('f2' ), correct )
769
- except AssertionError as exc :
770
+ except BaseException as exc :
770
771
exc .args += (arr ,)
771
772
raise
772
773
@@ -830,6 +831,121 @@ def test_non_convertable_values(self):
830
831
lambda : nanops ._ensure_numeric ([]))
831
832
832
833
834
+ class TestNanvarFixedValues (tm .TestCase ):
835
+
836
+ def setUp (self ):
837
+ # Samples from a normal distribution.
838
+ self .variance = variance = 3.0
839
+ self .samples = self .prng .normal (scale = variance ** 0.5 , size = 100000 )
840
+
841
+ def test_nanvar_all_finite (self ):
842
+ samples = self .samples
843
+ actual_variance = nanops .nanvar (samples )
844
+ np .testing .assert_almost_equal (
845
+ actual_variance , self .variance , decimal = 2 )
846
+
847
+ def test_nanvar_nans (self ):
848
+ samples = np .nan * np .ones (2 * self .samples .shape [0 ])
849
+ samples [::2 ] = self .samples
850
+
851
+ actual_variance = nanops .nanvar (samples , skipna = True )
852
+ np .testing .assert_almost_equal (
853
+ actual_variance , self .variance , decimal = 2 )
854
+
855
+ actual_variance = nanops .nanvar (samples , skipna = False )
856
+ np .testing .assert_almost_equal (
857
+ actual_variance , np .nan , decimal = 2 )
858
+
859
+ def test_nanstd_nans (self ):
860
+ samples = np .nan * np .ones (2 * self .samples .shape [0 ])
861
+ samples [::2 ] = self .samples
862
+
863
+ actual_std = nanops .nanstd (samples , skipna = True )
864
+ np .testing .assert_almost_equal (
865
+ actual_std , self .variance ** 0.5 , decimal = 2 )
866
+
867
+ actual_std = nanops .nanvar (samples , skipna = False )
868
+ np .testing .assert_almost_equal (
869
+ actual_std , np .nan , decimal = 2 )
870
+
871
+ def test_nanvar_axis (self ):
872
+ # Generate some sample data.
873
+ samples_norm = self .samples
874
+ samples_unif = self .prng .uniform (size = samples_norm .shape [0 ])
875
+ samples = np .vstack ([samples_norm , samples_unif ])
876
+
877
+ actual_variance = nanops .nanvar (samples , axis = 1 )
878
+ np .testing .assert_array_almost_equal (
879
+ actual_variance , np .array ([self .variance , 1.0 / 12 ]), decimal = 2 )
880
+
881
+ def test_nanvar_ddof (self ):
882
+ n = 5
883
+ samples = self .prng .uniform (size = (10000 , n + 1 ))
884
+ samples [:, - 1 ] = np .nan # Force use of our own algorithm.
885
+
886
+ variance_0 = nanops .nanvar (samples , axis = 1 , skipna = True , ddof = 0 ).mean ()
887
+ variance_1 = nanops .nanvar (samples , axis = 1 , skipna = True , ddof = 1 ).mean ()
888
+ variance_2 = nanops .nanvar (samples , axis = 1 , skipna = True , ddof = 2 ).mean ()
889
+
890
+ # The unbiased estimate.
891
+ var = 1.0 / 12
892
+ np .testing .assert_almost_equal (variance_1 , var , decimal = 2 )
893
+ # The underestimated variance.
894
+ np .testing .assert_almost_equal (
895
+ variance_0 , (n - 1.0 ) / n * var , decimal = 2 )
896
+ # The overestimated variance.
897
+ np .testing .assert_almost_equal (
898
+ variance_2 , (n - 1.0 ) / (n - 2.0 ) * var , decimal = 2 )
899
+
900
+ def test_ground_truth (self ):
901
+ # Test against values that were precomputed with Numpy.
902
+ samples = np .empty ((4 , 4 ))
903
+ samples [:3 , :3 ] = np .array ([[0.97303362 , 0.21869576 , 0.55560287 ],
904
+ [0.72980153 , 0.03109364 , 0.99155171 ],
905
+ [0.09317602 , 0.60078248 , 0.15871292 ]])
906
+ samples [3 ] = samples [:, 3 ] = np .nan
907
+
908
+ # Actual variances along axis=0, 1 for ddof=0, 1, 2
909
+ variance = np .array (
910
+ [[[0.13762259 , 0.05619224 , 0.11568816 ],
911
+ [0.20643388 , 0.08428837 , 0.17353224 ],
912
+ [0.41286776 , 0.16857673 , 0.34706449 ]],
913
+ [[0.09519783 , 0.16435395 , 0.05082054 ],
914
+ [0.14279674 , 0.24653093 , 0.07623082 ],
915
+ [0.28559348 , 0.49306186 , 0.15246163 ]]]
916
+ )
917
+
918
+ # Test nanvar.
919
+ for axis in range (2 ):
920
+ for ddof in range (3 ):
921
+ var = nanops .nanvar (samples , skipna = True , axis = axis , ddof = ddof )
922
+ np .testing .assert_array_almost_equal (
923
+ var [:3 ], variance [axis , ddof ]
924
+ )
925
+ np .testing .assert_equal (var [3 ], np .nan )
926
+
927
+ # Test nanstd.
928
+ for axis in range (2 ):
929
+ for ddof in range (3 ):
930
+ std = nanops .nanstd (samples , skipna = True , axis = axis , ddof = ddof )
931
+ np .testing .assert_array_almost_equal (
932
+ std [:3 ], variance [axis , ddof ] ** 0.5
933
+ )
934
+ np .testing .assert_equal (std [3 ], np .nan )
935
+
936
+ def test_nanstd_roundoff (self ):
937
+ # Regression test for GH 10242 (test data taken from GH 10489). Ensure
938
+ # that variance is stable.
939
+ data = Series (766897346 * np .ones (10 ))
940
+ for ddof in range (3 ):
941
+ result = data .std (ddof = ddof )
942
+ self .assertEqual (result , 0.0 )
943
+
944
+ @property
945
+ def prng (self ):
946
+ return np .random .RandomState (1234 )
947
+
948
+
833
949
if __name__ == '__main__' :
834
950
import nose
835
951
nose .runmodule (argv = [__file__ , '-vvs' , '-x' , '--pdb' , '--pdb-failure' ,
0 commit comments