diff options
Diffstat (limited to 'numpy/lib/tests')
24 files changed, 3145 insertions, 615 deletions
diff --git a/numpy/lib/tests/data/py2-objarr.npy b/numpy/lib/tests/data/py2-objarr.npy Binary files differnew file mode 100644 index 000000000..12936c92d --- /dev/null +++ b/numpy/lib/tests/data/py2-objarr.npy diff --git a/numpy/lib/tests/data/py2-objarr.npz b/numpy/lib/tests/data/py2-objarr.npz Binary files differnew file mode 100644 index 000000000..68a3b53a1 --- /dev/null +++ b/numpy/lib/tests/data/py2-objarr.npz diff --git a/numpy/lib/tests/data/py3-objarr.npy b/numpy/lib/tests/data/py3-objarr.npy Binary files differnew file mode 100644 index 000000000..6776074b4 --- /dev/null +++ b/numpy/lib/tests/data/py3-objarr.npy diff --git a/numpy/lib/tests/data/py3-objarr.npz b/numpy/lib/tests/data/py3-objarr.npz Binary files differnew file mode 100644 index 000000000..05eac0b76 --- /dev/null +++ b/numpy/lib/tests/data/py3-objarr.npz diff --git a/numpy/lib/tests/test__datasource.py b/numpy/lib/tests/test__datasource.py index 090f71f67..f4bece352 100644 --- a/numpy/lib/tests/test__datasource.py +++ b/numpy/lib/tests/test__datasource.py @@ -7,7 +7,7 @@ from shutil import rmtree from numpy.compat import asbytes from numpy.testing import ( - run_module_suite, TestCase, assert_ + run_module_suite, TestCase, assert_, SkipTest ) import numpy.lib._datasource as datasource @@ -137,8 +137,7 @@ class TestDataSourceOpen(TestCase): import gzip except ImportError: # We don't have the gzip capabilities to test. - import nose - raise nose.SkipTest + raise SkipTest # Test datasource's internal file_opener for Gzip files. filepath = os.path.join(self.tmpdir, 'foobar.txt.gz') fp = gzip.open(filepath, 'w') @@ -154,8 +153,7 @@ class TestDataSourceOpen(TestCase): import bz2 except ImportError: # We don't have the bz2 capabilities to test. - import nose - raise nose.SkipTest + raise SkipTest # Test datasource's internal file_opener for BZip2 files. filepath = os.path.join(self.tmpdir, 'foobar.txt.bz2') fp = bz2.BZ2File(filepath, 'w') diff --git a/numpy/lib/tests/test__iotools.py b/numpy/lib/tests/test__iotools.py index 4db19382a..e0a917a21 100644 --- a/numpy/lib/tests/test__iotools.py +++ b/numpy/lib/tests/test__iotools.py @@ -7,7 +7,8 @@ from datetime import date import numpy as np from numpy.compat import asbytes, asbytes_nested from numpy.testing import ( - run_module_suite, TestCase, assert_, assert_equal + run_module_suite, TestCase, assert_, assert_equal, assert_allclose, + assert_raises ) from numpy.lib._iotools import ( LineSplitter, NameValidator, StringConverter, @@ -76,7 +77,7 @@ class TestLineSplitter(TestCase): test = LineSplitter((6, 6, 9))(strg) assert_equal(test, asbytes_nested(['1', '3 4', '5 6'])) -#------------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- class TestNameValidator(TestCase): @@ -93,6 +94,9 @@ class TestNameValidator(TestCase): test = NameValidator(case_sensitive='lower').validate(names) assert_equal(test, ['a', 'a_1', 'b', 'c']) + # check exceptions + assert_raises(ValueError, NameValidator, case_sensitive='foobar') + def test_excludelist(self): "Test excludelist" names = ['dates', 'data', 'Other Data', 'mask'] @@ -127,7 +131,7 @@ class TestNameValidator(TestCase): assert_(validator(namelist) is None) assert_equal(validator(namelist, nbfields=3), ['f0', 'f1', 'f2']) -#------------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- def _bytes_to_date(s): @@ -148,15 +152,33 @@ class TestStringConverter(TestCase): def test_upgrade(self): "Tests the upgrade method." + converter = StringConverter() assert_equal(converter._status, 0) - converter.upgrade(asbytes('0')) + + # test int + assert_equal(converter.upgrade(asbytes('0')), 0) assert_equal(converter._status, 1) - converter.upgrade(asbytes('0.')) - assert_equal(converter._status, 2) - converter.upgrade(asbytes('0j')) - assert_equal(converter._status, 3) - converter.upgrade(asbytes('a')) + + # On systems where integer defaults to 32-bit, the statuses will be + # offset by one, so we check for this here. + import numpy.core.numeric as nx + status_offset = int(nx.dtype(nx.integer).itemsize < nx.dtype(nx.int64).itemsize) + + # test int > 2**32 + assert_equal(converter.upgrade(asbytes('17179869184')), 17179869184) + assert_equal(converter._status, 1 + status_offset) + + # test float + assert_allclose(converter.upgrade(asbytes('0.')), 0.0) + assert_equal(converter._status, 2 + status_offset) + + # test complex + assert_equal(converter.upgrade(asbytes('0j')), complex('0j')) + assert_equal(converter._status, 3 + status_offset) + + # test str + assert_equal(converter.upgrade(asbytes('a')), asbytes('a')) assert_equal(converter._status, len(converter._mapper) - 1) def test_missing(self): diff --git a/numpy/lib/tests/test__version.py b/numpy/lib/tests/test__version.py index bbafe68eb..993c9d507 100644 --- a/numpy/lib/tests/test__version.py +++ b/numpy/lib/tests/test__version.py @@ -48,6 +48,19 @@ def test_dev_a_b_rc_mixed(): assert_(NumpyVersion('1.9.0a2.dev-6acvda54') < '1.9.0a2') +def test_dev0_version(): + assert_(NumpyVersion('1.9.0.dev0+Unknown') < '1.9.0') + for ver in ['1.9.0', '1.9.0a1', '1.9.0b2', '1.9.0b2.dev0+ffffffff']: + assert_(NumpyVersion('1.9.0.dev0+f16acvda') < ver) + + assert_(NumpyVersion('1.9.0.dev0+f16acvda') == '1.9.0.dev0+11111111') + + +def test_dev0_a_b_rc_mixed(): + assert_(NumpyVersion('1.9.0a2.dev0+f16acvda') == '1.9.0a2.dev0+11111111') + assert_(NumpyVersion('1.9.0a2.dev0+6acvda54') < '1.9.0a2') + + def test_raises(): for ver in ['1.9', '1,9.0', '1.7.x']: assert_raises(ValueError, NumpyVersion, ver) diff --git a/numpy/lib/tests/test_arraypad.py b/numpy/lib/tests/test_arraypad.py index f8ba8643a..d037962e6 100644 --- a/numpy/lib/tests/test_arraypad.py +++ b/numpy/lib/tests/test_arraypad.py @@ -1,14 +1,57 @@ -"""Tests for the pad functions. +"""Tests for the array padding functions. """ from __future__ import division, absolute_import, print_function -from numpy.testing import TestCase, run_module_suite, assert_array_equal -from numpy.testing import assert_raises, assert_array_almost_equal import numpy as np +from numpy.testing import (assert_array_equal, assert_raises, assert_allclose, + TestCase) from numpy.lib import pad +class TestConditionalShortcuts(TestCase): + def test_zero_padding_shortcuts(self): + test = np.arange(120).reshape(4, 5, 6) + pad_amt = [(0, 0) for axis in test.shape] + modes = ['constant', + 'edge', + 'linear_ramp', + 'maximum', + 'mean', + 'median', + 'minimum', + 'reflect', + 'symmetric', + 'wrap', + ] + for mode in modes: + assert_array_equal(test, pad(test, pad_amt, mode=mode)) + + def test_shallow_statistic_range(self): + test = np.arange(120).reshape(4, 5, 6) + pad_amt = [(1, 1) for axis in test.shape] + modes = ['maximum', + 'mean', + 'median', + 'minimum', + ] + for mode in modes: + assert_array_equal(pad(test, pad_amt, mode='edge'), + pad(test, pad_amt, mode=mode, stat_length=1)) + + def test_clip_statistic_range(self): + test = np.arange(30).reshape(5, 6) + pad_amt = [(3, 3) for axis in test.shape] + modes = ['maximum', + 'mean', + 'median', + 'minimum', + ] + for mode in modes: + assert_array_equal(pad(test, pad_amt, mode=mode), + pad(test, pad_amt, mode=mode, stat_length=30)) + + class TestStatistic(TestCase): def test_check_mean_stat_length(self): a = np.arange(100).astype('f') @@ -82,6 +125,30 @@ class TestStatistic(TestCase): ) assert_array_equal(a, b) + def test_check_maximum_stat_length(self): + a = np.arange(100) + 1 + a = pad(a, (25, 20), 'maximum', stat_length=10) + b = np.array( + [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, + + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100] + ) + assert_array_equal(a, b) + def test_check_minimum_1(self): a = np.arange(100) a = pad(a, (25, 20), 'minimum') @@ -130,6 +197,30 @@ class TestStatistic(TestCase): ) assert_array_equal(a, b) + def test_check_minimum_stat_length(self): + a = np.arange(100) + 1 + a = pad(a, (25, 20), 'minimum', stat_length=10) + b = np.array( + [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91] + ) + assert_array_equal(a, b) + def test_check_median(self): a = np.arange(100).astype('f') a = pad(a, (25, 20), 'median') @@ -182,6 +273,32 @@ class TestStatistic(TestCase): ) assert_array_equal(a, b) + def test_check_median_stat_length(self): + a = np.arange(100).astype('f') + a[1] = 2. + a[97] = 96. + a = pad(a, (25, 20), 'median', stat_length=(3, 5)) + b = np.array( + [ 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., + 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., + 2., 2., 2., 2., 2., + + 0., 2., 2., 3., 4., 5., 6., 7., 8., 9., + 10., 11., 12., 13., 14., 15., 16., 17., 18., 19., + 20., 21., 22., 23., 24., 25., 26., 27., 28., 29., + 30., 31., 32., 33., 34., 35., 36., 37., 38., 39., + 40., 41., 42., 43., 44., 45., 46., 47., 48., 49., + 50., 51., 52., 53., 54., 55., 56., 57., 58., 59., + 60., 61., 62., 63., 64., 65., 66., 67., 68., 69., + 70., 71., 72., 73., 74., 75., 76., 77., 78., 79., + 80., 81., 82., 83., 84., 85., 86., 87., 88., 89., + 90., 91., 92., 93., 94., 95., 96., 96., 98., 99., + + 96., 96., 96., 96., 96., 96., 96., 96., 96., 96., + 96., 96., 96., 96., 96., 96., 96., 96., 96., 96.] + ) + assert_array_equal(a, b) + def test_check_mean_shape_one(self): a = [[4, 5, 6]] a = pad(a, (5, 7), 'mean', stat_length=2) @@ -254,6 +371,125 @@ class TestConstant(TestCase): ) assert_array_equal(a, b) + def test_check_constant_zeros(self): + a = np.arange(100) + a = pad(a, (25, 20), 'constant') + b = np.array( + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + ) + assert_array_equal(a, b) + + def test_check_constant_float(self): + # If input array is int, but constant_values are float, the dtype of + # the array to be padded is kept + arr = np.arange(30).reshape(5, 6) + test = pad(arr, (1, 2), mode='constant', + constant_values=1.1) + expected = np.array( + [[ 1, 1, 1, 1, 1, 1, 1, 1, 1], + + [ 1, 0, 1, 2, 3, 4, 5, 1, 1], + [ 1, 6, 7, 8, 9, 10, 11, 1, 1], + [ 1, 12, 13, 14, 15, 16, 17, 1, 1], + [ 1, 18, 19, 20, 21, 22, 23, 1, 1], + [ 1, 24, 25, 26, 27, 28, 29, 1, 1], + + [ 1, 1, 1, 1, 1, 1, 1, 1, 1], + [ 1, 1, 1, 1, 1, 1, 1, 1, 1]] + ) + assert_allclose(test, expected) + + def test_check_constant_float2(self): + # If input array is float, and constant_values are float, the dtype of + # the array to be padded is kept - here retaining the float constants + arr = np.arange(30).reshape(5, 6) + arr_float = arr.astype(np.float64) + test = pad(arr_float, ((1, 2), (1, 2)), mode='constant', + constant_values=1.1) + expected = np.array( + [[ 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1], + + [ 1.1, 0. , 1. , 2. , 3. , 4. , 5. , 1.1, 1.1], + [ 1.1, 6. , 7. , 8. , 9. , 10. , 11. , 1.1, 1.1], + [ 1.1, 12. , 13. , 14. , 15. , 16. , 17. , 1.1, 1.1], + [ 1.1, 18. , 19. , 20. , 21. , 22. , 23. , 1.1, 1.1], + [ 1.1, 24. , 25. , 26. , 27. , 28. , 29. , 1.1, 1.1], + + [ 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1], + [ 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1]] + ) + assert_allclose(test, expected) + + def test_check_constant_float3(self): + a = np.arange(100, dtype=float) + a = pad(a, (25, 20), 'constant', constant_values=(-1.1, -1.2)) + b = np.array( + [-1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, + -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, + -1.1, -1.1, -1.1, -1.1, -1.1, + + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + + -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, + -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2] + ) + assert_allclose(a, b) + + def test_check_constant_odd_pad_amount(self): + arr = np.arange(30).reshape(5, 6) + test = pad(arr, ((1,), (2,)), mode='constant', + constant_values=3) + expected = np.array( + [[ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3], + + [ 3, 3, 0, 1, 2, 3, 4, 5, 3, 3], + [ 3, 3, 6, 7, 8, 9, 10, 11, 3, 3], + [ 3, 3, 12, 13, 14, 15, 16, 17, 3, 3], + [ 3, 3, 18, 19, 20, 21, 22, 23, 3, 3], + [ 3, 3, 24, 25, 26, 27, 28, 29, 3, 3], + + [ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]] + ) + assert_allclose(test, expected) + + def test_check_constant_pad_2d(self): + arr = np.arange(4).reshape(2, 2) + test = np.lib.pad(arr, ((1, 2), (1, 3)), mode='constant', + constant_values=((1, 2), (3, 4))) + expected = np.array( + [[3, 1, 1, 4, 4, 4], + [3, 0, 1, 4, 4, 4], + [3, 2, 3, 4, 4, 4], + [3, 2, 2, 4, 4, 4], + [3, 2, 2, 4, 4, 4]] + ) + assert_allclose(test, expected) + class TestLinearRamp(TestCase): def test_check_simple(self): @@ -278,7 +514,21 @@ class TestLinearRamp(TestCase): 94.3, 89.6, 84.9, 80.2, 75.5, 70.8, 66.1, 61.4, 56.7, 52.0, 47.3, 42.6, 37.9, 33.2, 28.5, 23.8, 19.1, 14.4, 9.7, 5.] ) - assert_array_almost_equal(a, b, decimal=5) + assert_allclose(a, b, rtol=1e-5, atol=1e-5) + + def test_check_2d(self): + arr = np.arange(20).reshape(4, 5).astype(np.float64) + test = pad(arr, (2, 2), mode='linear_ramp', end_values=(0, 0)) + expected = np.array( + [[0., 0., 0., 0., 0., 0., 0., 0., 0.], + [0., 0., 0., 0.5, 1., 1.5, 2., 1., 0.], + [0., 0., 0., 1., 2., 3., 4., 2., 0.], + [0., 2.5, 5., 6., 7., 8., 9., 4.5, 0.], + [0., 5., 10., 11., 12., 13., 14., 7., 0.], + [0., 7.5, 15., 16., 17., 18., 19., 9.5, 0.], + [0., 3.75, 7.5, 8., 8.5, 9., 9.5, 4.75, 0.], + [0., 0., 0., 0., 0., 0., 0., 0., 0.]]) + assert_allclose(test, expected) class TestReflect(TestCase): @@ -306,6 +556,30 @@ class TestReflect(TestCase): ) assert_array_equal(a, b) + def test_check_odd_method(self): + a = np.arange(100) + a = pad(a, (25, 20), 'reflect', reflect_type='odd') + b = np.array( + [-25, -24, -23, -22, -21, -20, -19, -18, -17, -16, + -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, + -5, -4, -3, -2, -1, + + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119] + ) + assert_array_equal(a, b) + def test_check_large_pad(self): a = [[4, 5, 6], [6, 7, 8]] a = pad(a, (5, 7), 'reflect') @@ -367,6 +641,140 @@ class TestReflect(TestCase): assert_array_equal(a, b) +class TestSymmetric(TestCase): + def test_check_simple(self): + a = np.arange(100) + a = pad(a, (25, 20), 'symmetric') + b = np.array( + [24, 23, 22, 21, 20, 19, 18, 17, 16, 15, + 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, + 4, 3, 2, 1, 0, + + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + + 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, + 89, 88, 87, 86, 85, 84, 83, 82, 81, 80] + ) + assert_array_equal(a, b) + + def test_check_odd_method(self): + a = np.arange(100) + a = pad(a, (25, 20), 'symmetric', reflect_type='odd') + b = np.array( + [-24, -23, -22, -21, -20, -19, -18, -17, -16, -15, + -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, + -4, -3, -2, -1, 0, + + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118] + ) + assert_array_equal(a, b) + + def test_check_large_pad(self): + a = [[4, 5, 6], [6, 7, 8]] + a = pad(a, (5, 7), 'symmetric') + b = np.array( + [[5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8], + [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8], + + [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8], + [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6]] + ) + + assert_array_equal(a, b) + + def test_check_large_pad_odd(self): + a = [[4, 5, 6], [6, 7, 8]] + a = pad(a, (5, 7), 'symmetric', reflect_type='odd') + b = np.array( + [[-3, -2, -2, -1, 0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6], + [-3, -2, -2, -1, 0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6], + [-1, 0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8], + [-1, 0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8], + [ 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10], + + [ 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10], + [ 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12, 12], + + [ 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12, 12], + [ 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12, 12, 13, 14, 14], + [ 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12, 12, 13, 14, 14], + [ 7, 8, 8, 9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16], + [ 7, 8, 8, 9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16], + [ 9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18], + [ 9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18]] + ) + assert_array_equal(a, b) + + def test_check_shape(self): + a = [[4, 5, 6]] + a = pad(a, (5, 7), 'symmetric') + b = np.array( + [[5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6]] + ) + assert_array_equal(a, b) + + def test_check_01(self): + a = pad([1, 2, 3], 2, 'symmetric') + b = np.array([2, 1, 1, 2, 3, 3, 2]) + assert_array_equal(a, b) + + def test_check_02(self): + a = pad([1, 2, 3], 3, 'symmetric') + b = np.array([3, 2, 1, 1, 2, 3, 3, 2, 1]) + assert_array_equal(a, b) + + def test_check_03(self): + a = pad([1, 2, 3], 6, 'symmetric') + b = np.array([1, 2, 3, 3, 2, 1, 1, 2, 3, 3, 2, 1, 1, 2, 3]) + assert_array_equal(a, b) + + class TestWrap(TestCase): def test_check_simple(self): a = np.arange(100) @@ -506,6 +914,24 @@ class TestEdge(TestCase): ) assert_array_equal(a, b) + def test_check_width_shape_1_2(self): + # Check a pad_width of the form ((1, 2),). + # Regression test for issue gh-7808. + a = np.array([1, 2, 3]) + padded = pad(a, ((1, 2),), 'edge') + expected = np.array([1, 1, 2, 3, 3, 3]) + assert_array_equal(padded, expected) + + a = np.array([[1, 2, 3], [4, 5, 6]]) + padded = pad(a, ((1, 2),), 'edge') + expected = pad(a, ((1, 2), (1, 2)), 'edge') + assert_array_equal(padded, expected) + + a = np.arange(24).reshape(2, 3, 4) + padded = pad(a, ((1, 2),), 'edge') + expected = pad(a, ((1, 2), (1, 2), (1, 2)), 'edge') + assert_array_equal(padded, expected) + class TestZeroPadWidth(TestCase): def test_zero_pad_width(self): @@ -515,6 +941,60 @@ class TestZeroPadWidth(TestCase): assert_array_equal(arr, pad(arr, pad_width, mode='constant')) +class TestLegacyVectorFunction(TestCase): + def test_legacy_vector_functionality(self): + def _padwithtens(vector, pad_width, iaxis, kwargs): + vector[:pad_width[0]] = 10 + vector[-pad_width[1]:] = 10 + return vector + + a = np.arange(6).reshape(2, 3) + a = pad(a, 2, _padwithtens) + b = np.array( + [[10, 10, 10, 10, 10, 10, 10], + [10, 10, 10, 10, 10, 10, 10], + + [10, 10, 0, 1, 2, 10, 10], + [10, 10, 3, 4, 5, 10, 10], + + [10, 10, 10, 10, 10, 10, 10], + [10, 10, 10, 10, 10, 10, 10]] + ) + assert_array_equal(a, b) + + +class TestNdarrayPadWidth(TestCase): + def test_check_simple(self): + a = np.arange(12) + a = np.reshape(a, (4, 3)) + a = pad(a, np.array(((2, 3), (3, 2))), 'edge') + b = np.array( + [[0, 0, 0, 0, 1, 2, 2, 2], + [0, 0, 0, 0, 1, 2, 2, 2], + + [0, 0, 0, 0, 1, 2, 2, 2], + [3, 3, 3, 3, 4, 5, 5, 5], + [6, 6, 6, 6, 7, 8, 8, 8], + [9, 9, 9, 9, 10, 11, 11, 11], + + [9, 9, 9, 9, 10, 11, 11, 11], + [9, 9, 9, 9, 10, 11, 11, 11], + [9, 9, 9, 9, 10, 11, 11, 11]] + ) + assert_array_equal(a, b) + + +class TestUnicodeInput(TestCase): + def test_unicode_mode(self): + try: + constant_mode = unicode('constant') + except NameError: + constant_mode = 'constant' + a = np.pad([1], 2, mode=constant_mode) + b = np.array([0, 0, 1, 0, 0]) + assert_array_equal(a, b) + + class ValueError1(TestCase): def test_check_simple(self): arr = np.arange(30) @@ -539,22 +1019,71 @@ class ValueError1(TestCase): class ValueError2(TestCase): - def test_check_simple(self): + def test_check_negative_pad_amount(self): arr = np.arange(30) arr = np.reshape(arr, (6, 5)) kwargs = dict(mode='mean', stat_length=(3, )) - assert_raises(ValueError, pad, arr, ((2, 3, 4), (3, 2)), + assert_raises(ValueError, pad, arr, ((-2, 3), (3, 2)), **kwargs) class ValueError3(TestCase): - def test_check_simple(self): + def test_check_kwarg_not_allowed(self): + arr = np.arange(30).reshape(5, 6) + assert_raises(ValueError, pad, arr, 4, mode='mean', + reflect_type='odd') + + def test_mode_not_set(self): + arr = np.arange(30).reshape(5, 6) + assert_raises(TypeError, pad, arr, 4) + + def test_malformed_pad_amount(self): + arr = np.arange(30).reshape(5, 6) + assert_raises(ValueError, pad, arr, (4, 5, 6, 7), mode='constant') + + def test_malformed_pad_amount2(self): + arr = np.arange(30).reshape(5, 6) + assert_raises(ValueError, pad, arr, ((3, 4, 5), (0, 1, 2)), + mode='constant') + + def test_pad_too_many_axes(self): + arr = np.arange(30).reshape(5, 6) + + # Attempt to pad using a 3D array equivalent + bad_shape = (((3,), (4,), (5,)), ((0,), (1,), (2,))) + assert_raises(ValueError, pad, arr, bad_shape, + mode='constant') + + +class TypeError1(TestCase): + def test_float(self): + arr = np.arange(30) + assert_raises(TypeError, pad, arr, ((-2.1, 3), (3, 2))) + assert_raises(TypeError, pad, arr, np.array(((-2.1, 3), (3, 2)))) + + def test_str(self): + arr = np.arange(30) + assert_raises(TypeError, pad, arr, 'foo') + assert_raises(TypeError, pad, arr, np.array('foo')) + + def test_object(self): + class FooBar(object): + pass + arr = np.arange(30) + assert_raises(TypeError, pad, arr, FooBar()) + + def test_complex(self): + arr = np.arange(30) + assert_raises(TypeError, pad, arr, complex(1, -1)) + assert_raises(TypeError, pad, arr, np.array(complex(1, -1))) + + def test_check_wrong_pad_amount(self): arr = np.arange(30) arr = np.reshape(arr, (6, 5)) kwargs = dict(mode='mean', stat_length=(3, )) - assert_raises(ValueError, pad, arr, ((-2, 3), (3, 2)), + assert_raises(TypeError, pad, arr, ((2, 3, 4), (3, 2)), **kwargs) if __name__ == "__main__": - run_module_suite() + np.testing.run_module_suite() diff --git a/numpy/lib/tests/test_arraysetops.py b/numpy/lib/tests/test_arraysetops.py index 39196f4bc..75918fbee 100644 --- a/numpy/lib/tests/test_arraysetops.py +++ b/numpy/lib/tests/test_arraysetops.py @@ -5,7 +5,7 @@ from __future__ import division, absolute_import, print_function import numpy as np from numpy.testing import ( - run_module_suite, TestCase, assert_array_equal + run_module_suite, TestCase, assert_array_equal, assert_equal ) from numpy.lib.arraysetops import ( ediff1d, intersect1d, setxor1d, union1d, setdiff1d, unique, in1d @@ -169,6 +169,14 @@ class TestSetOps(TestCase): assert_array_equal([-1, 0], ediff1d(zero_elem, to_begin=-1, to_end=0)) assert_array_equal([], ediff1d(one_elem)) assert_array_equal([1], ediff1d(two_elem)) + assert_array_equal([7,1,9], ediff1d(two_elem, to_begin=7, to_end=9)) + assert_array_equal([5,6,1,7,8], ediff1d(two_elem, to_begin=[5,6], to_end=[7,8])) + assert_array_equal([1,9], ediff1d(two_elem, to_end=9)) + assert_array_equal([1,7,8], ediff1d(two_elem, to_end=[7,8])) + assert_array_equal([7,1], ediff1d(two_elem, to_begin=7)) + assert_array_equal([5,6,1], ediff1d(two_elem, to_begin=[5,6])) + assert(isinstance(ediff1d(np.matrix(1)), np.matrix)) + assert(isinstance(ediff1d(np.matrix(1), to_begin=1), np.matrix)) def test_in1d(self): # we use two different sizes for the b array here to test the @@ -286,6 +294,8 @@ class TestSetOps(TestCase): assert_array_equal(c, ec) assert_array_equal([], setdiff1d([], [])) + a = np.array((), np.uint32) + assert_equal(setdiff1d(a, []).dtype, np.uint32) def test_setdiff1d_char_array(self): a = np.array(['a', 'b', 'c']) diff --git a/numpy/lib/tests/test_financial.py b/numpy/lib/tests/test_financial.py index a4b9cfe2e..cc8ba55e5 100644 --- a/numpy/lib/tests/test_financial.py +++ b/numpy/lib/tests/test_financial.py @@ -2,7 +2,8 @@ from __future__ import division, absolute_import, print_function import numpy as np from numpy.testing import ( - run_module_suite, TestCase, assert_, assert_almost_equal + run_module_suite, TestCase, assert_, assert_almost_equal, + assert_allclose, assert_equal ) @@ -13,35 +14,42 @@ class TestFinancial(TestCase): def test_irr(self): v = [-150000, 15000, 25000, 35000, 45000, 60000] - assert_almost_equal(np.irr(v), - 0.0524, 2) + assert_almost_equal(np.irr(v), 0.0524, 2) v = [-100, 0, 0, 74] - assert_almost_equal(np.irr(v), - -0.0955, 2) + assert_almost_equal(np.irr(v), -0.0955, 2) v = [-100, 39, 59, 55, 20] - assert_almost_equal(np.irr(v), - 0.28095, 2) + assert_almost_equal(np.irr(v), 0.28095, 2) v = [-100, 100, 0, -7] - assert_almost_equal(np.irr(v), - -0.0833, 2) + assert_almost_equal(np.irr(v), -0.0833, 2) v = [-100, 100, 0, 7] - assert_almost_equal(np.irr(v), - 0.06206, 2) + assert_almost_equal(np.irr(v), 0.06206, 2) v = [-5, 10.5, 1, -8, 1] - assert_almost_equal(np.irr(v), - 0.0886, 2) + assert_almost_equal(np.irr(v), 0.0886, 2) + + # Test that if there is no solution then np.irr returns nan + # Fixes gh-6744 + v = [-1, -2, -3] + assert_equal(np.irr(v), np.nan) def test_pv(self): - assert_almost_equal(np.pv(0.07, 20, 12000, 0), - -127128.17, 2) + assert_almost_equal(np.pv(0.07, 20, 12000, 0), -127128.17, 2) def test_fv(self): - assert_almost_equal(np.fv(0.075, 20, -2000, 0, 0), - 86609.36, 2) + assert_almost_equal(np.fv(0.075, 20, -2000, 0, 0), 86609.36, 2) def test_pmt(self): - assert_almost_equal(np.pmt(0.08/12, 5*12, 15000), - -304.146, 3) + res = np.pmt(0.08/12, 5*12, 15000) + tgt = -304.145914 + assert_allclose(res, tgt) + # Test the edge case where rate == 0.0 + res = np.pmt(0.0, 5*12, 15000) + tgt = -250.0 + assert_allclose(res, tgt) + # Test the case where we use broadcast and + # the arguments passed in are arrays. + res = np.pmt([[0.0, 0.8],[0.3, 0.8]],[12, 3],[2000, 20000]) + tgt = np.array([[-166.66667, -19311.258],[-626.90814, -19311.258]]) + assert_allclose(res, tgt) def test_ppmt(self): np.round(np.ppmt(0.1/12, 1, 60, 55000), 2) == 710.25 diff --git a/numpy/lib/tests/test_format.py b/numpy/lib/tests/test_format.py index ee77386bc..892b32a9c 100644 --- a/numpy/lib/tests/test_format.py +++ b/numpy/lib/tests/test_format.py @@ -112,7 +112,7 @@ Test the header writing. >>> for arr in basic_arrays + record_arrays: ... f = BytesIO() ... format.write_array_header_1_0(f, arr) # XXX: arr is not a dict, items gets called on it - ... print repr(f.getvalue()) + ... print(repr(f.getvalue())) ... "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': (0,)} \n" "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': ()} \n" @@ -284,10 +284,10 @@ import warnings from io import BytesIO import numpy as np -from numpy.compat import asbytes, asbytes_nested +from numpy.compat import asbytes, asbytes_nested, sixu from numpy.testing import ( run_module_suite, assert_, assert_array_equal, assert_raises, raises, - dec + dec, SkipTest ) from numpy.lib import format @@ -534,6 +534,87 @@ def test_python2_python3_interoperability(): assert_array_equal(data, np.ones(2)) +def test_pickle_python2_python3(): + # Test that loading object arrays saved on Python 2 works both on + # Python 2 and Python 3 and vice versa + data_dir = os.path.join(os.path.dirname(__file__), 'data') + + if sys.version_info[0] >= 3: + xrange = range + else: + import __builtin__ + xrange = __builtin__.xrange + + expected = np.array([None, xrange, sixu('\u512a\u826f'), + asbytes('\xe4\xb8\x8d\xe8\x89\xaf')], + dtype=object) + + for fname in ['py2-objarr.npy', 'py2-objarr.npz', + 'py3-objarr.npy', 'py3-objarr.npz']: + path = os.path.join(data_dir, fname) + + if (fname.endswith('.npz') and sys.version_info[0] == 2 and + sys.version_info[1] < 7): + # Reading object arrays directly from zipfile appears to fail + # on Py2.6, see cfae0143b4 + continue + + for encoding in ['bytes', 'latin1']: + if (sys.version_info[0] >= 3 and sys.version_info[1] < 4 and + encoding == 'bytes'): + # The bytes encoding is available starting from Python 3.4 + continue + + data_f = np.load(path, encoding=encoding) + if fname.endswith('.npz'): + data = data_f['x'] + data_f.close() + else: + data = data_f + + if sys.version_info[0] >= 3: + if encoding == 'latin1' and fname.startswith('py2'): + assert_(isinstance(data[3], str)) + assert_array_equal(data[:-1], expected[:-1]) + # mojibake occurs + assert_array_equal(data[-1].encode(encoding), expected[-1]) + else: + assert_(isinstance(data[3], bytes)) + assert_array_equal(data, expected) + else: + assert_array_equal(data, expected) + + if sys.version_info[0] >= 3: + if fname.startswith('py2'): + if fname.endswith('.npz'): + data = np.load(path) + assert_raises(UnicodeError, data.__getitem__, 'x') + data.close() + data = np.load(path, fix_imports=False, encoding='latin1') + assert_raises(ImportError, data.__getitem__, 'x') + data.close() + else: + assert_raises(UnicodeError, np.load, path) + assert_raises(ImportError, np.load, path, + encoding='latin1', fix_imports=False) + + +def test_pickle_disallow(): + data_dir = os.path.join(os.path.dirname(__file__), 'data') + + path = os.path.join(data_dir, 'py2-objarr.npy') + assert_raises(ValueError, np.load, path, + allow_pickle=False, encoding='latin1') + + path = os.path.join(data_dir, 'py2-objarr.npz') + f = np.load(path, allow_pickle=False, encoding='latin1') + assert_raises(ValueError, f.__getitem__, 'x') + + path = os.path.join(tempdir, 'pickle-disabled.npy') + assert_raises(ValueError, np.save, path, np.array([None], dtype=object), + allow_pickle=False) + + def test_version_2_0(): f = BytesIO() # requires more than 2 byte for header @@ -554,6 +635,7 @@ def test_version_2_0(): assert_raises(ValueError, format.write_array, f, d, (1, 0)) +@dec.slow def test_version_2_0_memmap(): # requires more than 2 byte for header dt = [(("%d" % i) * 100, float) for i in range(500)] @@ -629,6 +711,26 @@ malformed_magic = asbytes_nested([ '', ]) +def test_read_magic(): + s1 = BytesIO() + s2 = BytesIO() + + arr = np.ones((3, 6), dtype=float) + + format.write_array(s1, arr, version=(1, 0)) + format.write_array(s2, arr, version=(2, 0)) + + s1.seek(0) + s2.seek(0) + + version1 = format.read_magic(s1) + version2 = format.read_magic(s2) + + assert_(version1 == (1, 0)) + assert_(version2 == (2, 0)) + + assert_(s1.tell() == format.MAGIC_LEN) + assert_(s2.tell() == format.MAGIC_LEN) def test_read_magic_bad_magic(): for magic in malformed_magic: @@ -659,6 +761,30 @@ def test_large_header(): assert_raises(ValueError, format.write_array_header_1_0, s, d) +def test_read_array_header_1_0(): + s = BytesIO() + + arr = np.ones((3, 6), dtype=float) + format.write_array(s, arr, version=(1, 0)) + + s.seek(format.MAGIC_LEN) + shape, fortran, dtype = format.read_array_header_1_0(s) + + assert_((shape, fortran, dtype) == ((3, 6), False, float)) + + +def test_read_array_header_2_0(): + s = BytesIO() + + arr = np.ones((3, 6), dtype=float) + format.write_array(s, arr, version=(2, 0)) + + s.seek(format.MAGIC_LEN) + shape, fortran, dtype = format.read_array_header_2_0(s) + + assert_((shape, fortran, dtype) == ((3, 6), False, float)) + + def test_bad_header(): # header of length less than 2 should fail s = BytesIO() @@ -687,7 +813,6 @@ def test_bad_header(): def test_large_file_support(): - from nose import SkipTest if (sys.platform == 'win32' or sys.platform == 'cygwin'): raise SkipTest("Unknown if Windows has sparse filesystems") # try creating a large sparse file @@ -712,5 +837,26 @@ def test_large_file_support(): assert_array_equal(r, d) +@dec.slow +@dec.skipif(np.dtype(np.intp).itemsize < 8, "test requires 64-bit system") +def test_large_archive(): + # Regression test for product of saving arrays with dimensions of array + # having a product that doesn't fit in int32. See gh-7598 for details. + try: + a = np.empty((2**30, 2), dtype=np.uint8) + except MemoryError: + raise SkipTest("Could not create large file") + + fname = os.path.join(tempdir, "large_archive") + + with open(fname, "wb") as f: + np.savez(f, arr=a) + + with open(fname, "rb") as f: + new_a = np.load(f)["arr"] + + assert_(a.shape == new_a.shape) + + if __name__ == "__main__": run_module_suite() diff --git a/numpy/lib/tests/test_function_base.py b/numpy/lib/tests/test_function_base.py index cdc4285e8..f396e036b 100644 --- a/numpy/lib/tests/test_function_base.py +++ b/numpy/lib/tests/test_function_base.py @@ -1,5 +1,6 @@ from __future__ import division, absolute_import, print_function +import operator import warnings import sys @@ -8,14 +9,170 @@ from numpy.testing import ( run_module_suite, TestCase, assert_, assert_equal, assert_array_equal, assert_almost_equal, assert_array_almost_equal, assert_raises, assert_allclose, assert_array_max_ulp, assert_warns, - assert_raises_regex, dec - ) + assert_raises_regex, dec, suppress_warnings +) +from numpy.testing.utils import HAS_REFCOUNT +import numpy.lib.function_base as nfb from numpy.random import rand -from numpy.lib import * +from numpy.lib import ( + add_newdoc_ufunc, angle, average, bartlett, blackman, corrcoef, cov, + delete, diff, digitize, extract, flipud, gradient, hamming, hanning, + histogram, histogramdd, i0, insert, interp, kaiser, meshgrid, msort, + piecewise, place, rot90, select, setxor1d, sinc, split, trapz, trim_zeros, + unwrap, unique, vectorize +) + from numpy.compat import long +def get_mat(n): + data = np.arange(n) + data = np.add.outer(data, data) + return data + + +class TestRot90(TestCase): + def test_basic(self): + self.assertRaises(ValueError, rot90, np.ones(4)) + assert_raises(ValueError, rot90, np.ones((2,2,2)), axes=(0,1,2)) + assert_raises(ValueError, rot90, np.ones((2,2)), axes=(0,2)) + assert_raises(ValueError, rot90, np.ones((2,2)), axes=(1,1)) + assert_raises(ValueError, rot90, np.ones((2,2,2)), axes=(-2,1)) + + a = [[0, 1, 2], + [3, 4, 5]] + b1 = [[2, 5], + [1, 4], + [0, 3]] + b2 = [[5, 4, 3], + [2, 1, 0]] + b3 = [[3, 0], + [4, 1], + [5, 2]] + b4 = [[0, 1, 2], + [3, 4, 5]] + + for k in range(-3, 13, 4): + assert_equal(rot90(a, k=k), b1) + for k in range(-2, 13, 4): + assert_equal(rot90(a, k=k), b2) + for k in range(-1, 13, 4): + assert_equal(rot90(a, k=k), b3) + for k in range(0, 13, 4): + assert_equal(rot90(a, k=k), b4) + + assert_equal(rot90(rot90(a, axes=(0,1)), axes=(1,0)), a) + assert_equal(rot90(a, k=1, axes=(1,0)), rot90(a, k=-1, axes=(0,1))) + + def test_axes(self): + a = np.ones((50, 40, 3)) + assert_equal(rot90(a).shape, (40, 50, 3)) + assert_equal(rot90(a, axes=(0,2)), rot90(a, axes=(0,-1))) + assert_equal(rot90(a, axes=(1,2)), rot90(a, axes=(-2,-1))) + + def test_rotation_axes(self): + a = np.arange(8).reshape((2,2,2)) + + a_rot90_01 = [[[2, 3], + [6, 7]], + [[0, 1], + [4, 5]]] + a_rot90_12 = [[[1, 3], + [0, 2]], + [[5, 7], + [4, 6]]] + a_rot90_20 = [[[4, 0], + [6, 2]], + [[5, 1], + [7, 3]]] + a_rot90_10 = [[[4, 5], + [0, 1]], + [[6, 7], + [2, 3]]] + + assert_equal(rot90(a, axes=(0, 1)), a_rot90_01) + assert_equal(rot90(a, axes=(1, 0)), a_rot90_10) + assert_equal(rot90(a, axes=(1, 2)), a_rot90_12) + + for k in range(1,5): + assert_equal(rot90(a, k=k, axes=(2, 0)), + rot90(a_rot90_20, k=k-1, axes=(2, 0))) + + +class TestFlip(TestCase): + + def test_axes(self): + self.assertRaises(ValueError, np.flip, np.ones(4), axis=1) + self.assertRaises(ValueError, np.flip, np.ones((4, 4)), axis=2) + self.assertRaises(ValueError, np.flip, np.ones((4, 4)), axis=-3) + + def test_basic_lr(self): + a = get_mat(4) + b = a[:, ::-1] + assert_equal(np.flip(a, 1), b) + a = [[0, 1, 2], + [3, 4, 5]] + b = [[2, 1, 0], + [5, 4, 3]] + assert_equal(np.flip(a, 1), b) + + def test_basic_ud(self): + a = get_mat(4) + b = a[::-1, :] + assert_equal(np.flip(a, 0), b) + a = [[0, 1, 2], + [3, 4, 5]] + b = [[3, 4, 5], + [0, 1, 2]] + assert_equal(np.flip(a, 0), b) + + def test_3d_swap_axis0(self): + a = np.array([[[0, 1], + [2, 3]], + [[4, 5], + [6, 7]]]) + + b = np.array([[[4, 5], + [6, 7]], + [[0, 1], + [2, 3]]]) + + assert_equal(np.flip(a, 0), b) + + def test_3d_swap_axis1(self): + a = np.array([[[0, 1], + [2, 3]], + [[4, 5], + [6, 7]]]) + + b = np.array([[[2, 3], + [0, 1]], + [[6, 7], + [4, 5]]]) + + assert_equal(np.flip(a, 1), b) + + def test_3d_swap_axis2(self): + a = np.array([[[0, 1], + [2, 3]], + [[4, 5], + [6, 7]]]) + + b = np.array([[[1, 0], + [3, 2]], + [[5, 4], + [7, 6]]]) + + assert_equal(np.flip(a, 2), b) + + def test_4d(self): + a = np.arange(2 * 3 * 4 * 5).reshape(2, 3, 4, 5) + for i in range(a.ndim): + assert_equal(np.flip(a, i), np.flipud(a.swapaxes(0, i)).swapaxes(i, 0)) + + class TestAny(TestCase): + def test_basic(self): y1 = [0, 0, 1, 0] y2 = [0, 0, 0, 0] @@ -32,6 +189,7 @@ class TestAny(TestCase): class TestAll(TestCase): + def test_basic(self): y1 = [0, 1, 1, 0] y2 = [0, 0, 0, 0] @@ -49,6 +207,7 @@ class TestAll(TestCase): class TestCopy(TestCase): + def test_basic(self): a = np.array([[1, 2], [3, 4]]) a_copy = np.copy(a) @@ -76,6 +235,7 @@ class TestCopy(TestCase): class TestAverage(TestCase): + def test_basic(self): y1 = np.array([1, 2, 3]) assert_(average(y1, axis=0) == 2.) @@ -101,7 +261,7 @@ class TestAverage(TestCase): y = np.arange(10) w = np.arange(10) actual = average(y, weights=w) - desired = (np.arange(10) ** 2).sum()*1. / np.arange(10).sum() + desired = (np.arange(10) ** 2).sum() * 1. / np.arange(10).sum() assert_almost_equal(actual, desired) y1 = np.array([[1, 2, 3], [4, 5, 6]]) @@ -155,6 +315,33 @@ class TestAverage(TestCase): avg, scl = average(y, weights=w2, axis=1, returned=True) assert_array_equal(scl, np.array([1., 6.])) + def test_subclasses(self): + class subclass(np.ndarray): + pass + a = np.array([[1,2],[3,4]]).view(subclass) + w = np.array([[1,2],[3,4]]).view(subclass) + + with suppress_warnings() as sup: + # Note that the warning is spurious, because the test checks + # for weights while a is ignored. + sup.filter(FutureWarning, "np.average currently does not preserve") + assert_equal(type(np.average(a, weights=w)), subclass) + + # also test matrices + a = np.matrix([[1,2],[3,4]]) + w = np.matrix([[1,2],[3,4]]) + + r = np.average(a, axis=0, weights=w) + assert_equal(type(r), np.matrix) + assert_equal(r, [[2.5, 10.0/3]]) + + def test_upcasting(self): + types = [('i4', 'i4', 'f8'), ('i4', 'f4', 'f8'), ('f4', 'i4', 'f8'), + ('f4', 'f4', 'f4'), ('f4', 'f8', 'f8')] + for at, wt, rt in types: + a = np.array([[1,2],[3,4]], dtype=at) + w = np.array([[1,2],[3,4]], dtype=wt) + assert_equal(np.average(a, weights=w).dtype, np.dtype(rt)) class TestSelect(TestCase): choices = [np.array([1, 2, 3]), @@ -229,6 +416,7 @@ class TestSelect(TestCase): class TestInsert(TestCase): + def test_basic(self): a = [1, 2, 3] assert_equal(insert(a, 0, 1), [1, 1, 2, 3]) @@ -242,11 +430,11 @@ class TestInsert(TestCase): assert_equal(insert(b, 0, b[0]), [0., 0., 1.]) assert_equal(insert(b, [], []), b) # Bools will be treated differently in the future: - #assert_equal(insert(a, np.array([True]*4), 9), [9,1,9,2,9,3,9]) + # assert_equal(insert(a, np.array([True]*4), 9), [9, 1, 9, 2, 9, 3, 9]) with warnings.catch_warnings(record=True) as w: warnings.filterwarnings('always', '', FutureWarning) assert_equal( - insert(a, np.array([True]*4), 9), [1, 9, 9, 9, 9, 2, 3]) + insert(a, np.array([True] * 4), 9), [1, 9, 9, 9, 9, 2, 3]) assert_(w[0].category is FutureWarning) def test_multidim(self): @@ -271,25 +459,25 @@ class TestInsert(TestCase): a = np.arange(4).reshape(2, 2) assert_equal(insert(a[:, :1], 1, a[:, 1], axis=1), a) - assert_equal(insert(a[:1, :], 1, a[1, :], axis=0), a) + assert_equal(insert(a[:1,:], 1, a[1,:], axis=0), a) # negative axis value a = np.arange(24).reshape((2, 3, 4)) - assert_equal(insert(a, 1, a[:, :, 3], axis=-1), - insert(a, 1, a[:, :, 3], axis=2)) - assert_equal(insert(a, 1, a[:, 2, :], axis=-2), - insert(a, 1, a[:, 2, :], axis=1)) + assert_equal(insert(a, 1, a[:,:, 3], axis=-1), + insert(a, 1, a[:,:, 3], axis=2)) + assert_equal(insert(a, 1, a[:, 2,:], axis=-2), + insert(a, 1, a[:, 2,:], axis=1)) # invalid axis value assert_raises(IndexError, insert, a, 1, a[:, 2, :], axis=3) assert_raises(IndexError, insert, a, 1, a[:, 2, :], axis=-4) # negative axis value - a = np.arange(24).reshape((2,3,4)) - assert_equal(insert(a, 1, a[:,:,3], axis=-1), - insert(a, 1, a[:,:,3], axis=2)) - assert_equal(insert(a, 1, a[:,2,:], axis=-2), - insert(a, 1, a[:,2,:], axis=1)) + a = np.arange(24).reshape((2, 3, 4)) + assert_equal(insert(a, 1, a[:, :, 3], axis=-1), + insert(a, 1, a[:, :, 3], axis=2)) + assert_equal(insert(a, 1, a[:, 2, :], axis=-2), + insert(a, 1, a[:, 2, :], axis=1)) def test_0d(self): # This is an error in the future @@ -329,6 +517,7 @@ class TestInsert(TestCase): class TestAmax(TestCase): + def test_basic(self): a = [3, 4, 5, 10, -3, -5, 6.0] assert_equal(np.amax(a), 10.0) @@ -340,6 +529,7 @@ class TestAmax(TestCase): class TestAmin(TestCase): + def test_basic(self): a = [3, 4, 5, 10, -3, -5, 6.0] assert_equal(np.amin(a), -5.0) @@ -351,17 +541,19 @@ class TestAmin(TestCase): class TestPtp(TestCase): + def test_basic(self): - a = [3, 4, 5, 10, -3, -5, 6.0] - assert_equal(np.ptp(a, axis=0), 15.0) - b = [[3, 6.0, 9.0], - [4, 10.0, 5.0], - [8, 3.0, 2.0]] - assert_equal(np.ptp(b, axis=0), [5.0, 7.0, 7.0]) - assert_equal(np.ptp(b, axis=-1), [6.0, 6.0, 6.0]) + a = np.array([3, 4, 5, 10, -3, -5, 6.0]) + assert_equal(a.ptp(axis=0), 15.0) + b = np.array([[3, 6.0, 9.0], + [4, 10.0, 5.0], + [8, 3.0, 2.0]]) + assert_equal(b.ptp(axis=0), [5.0, 7.0, 7.0]) + assert_equal(b.ptp(axis=-1), [6.0, 6.0, 6.0]) class TestCumsum(TestCase): + def test_basic(self): ba = [1, 2, 10, 11, 6, 5, 4] ba2 = [[1, 2, 3, 4], [5, 6, 7, 9], [10, 3, 4, 5]] @@ -383,6 +575,7 @@ class TestCumsum(TestCase): class TestProd(TestCase): + def test_basic(self): ba = [1, 2, 10, 11, 6, 5, 4] ba2 = [[1, 2, 3, 4], [5, 6, 7, 9], [10, 3, 4, 5]] @@ -391,18 +584,18 @@ class TestProd(TestCase): a = np.array(ba, ctype) a2 = np.array(ba2, ctype) if ctype in ['1', 'b']: - self.assertRaises(ArithmeticError, prod, a) - self.assertRaises(ArithmeticError, prod, a2, 1) - self.assertRaises(ArithmeticError, prod, a) + self.assertRaises(ArithmeticError, np.prod, a) + self.assertRaises(ArithmeticError, np.prod, a2, 1) else: - assert_equal(np.prod(a, axis=0), 26400) - assert_array_equal(np.prod(a2, axis=0), + assert_equal(a.prod(axis=0), 26400) + assert_array_equal(a2.prod(axis=0), np.array([50, 36, 84, 180], ctype)) - assert_array_equal(np.prod(a2, axis=-1), + assert_array_equal(a2.prod(axis=-1), np.array([24, 1890, 600], ctype)) class TestCumprod(TestCase): + def test_basic(self): ba = [1, 2, 10, 11, 6, 5, 4] ba2 = [[1, 2, 3, 4], [5, 6, 7, 9], [10, 3, 4, 5]] @@ -411,9 +604,9 @@ class TestCumprod(TestCase): a = np.array(ba, ctype) a2 = np.array(ba2, ctype) if ctype in ['1', 'b']: - self.assertRaises(ArithmeticError, cumprod, a) - self.assertRaises(ArithmeticError, cumprod, a2, 1) - self.assertRaises(ArithmeticError, cumprod, a) + self.assertRaises(ArithmeticError, np.cumprod, a) + self.assertRaises(ArithmeticError, np.cumprod, a2, 1) + self.assertRaises(ArithmeticError, np.cumprod, a) else: assert_array_equal(np.cumprod(a, axis=-1), np.array([1, 2, 20, 220, @@ -429,6 +622,7 @@ class TestCumprod(TestCase): class TestDiff(TestCase): + def test_basic(self): x = [1, 4, 6, 7, 12] out = np.array([3, 2, 1, 5]) @@ -451,6 +645,7 @@ class TestDiff(TestCase): class TestDelete(TestCase): + def setUp(self): self.a = np.arange(5) self.nd_a = np.arange(5).repeat(2).reshape(1, 5, 2) @@ -465,8 +660,8 @@ class TestDelete(TestCase): indices = indices[(indices >= 0) & (indices < 5)] assert_array_equal(setxor1d(a_del, self.a[indices, ]), self.a, err_msg=msg) - xor = setxor1d(nd_a_del[0, :, 0], self.nd_a[0, indices, 0]) - assert_array_equal(xor, self.nd_a[0, :, 0], err_msg=msg) + xor = setxor1d(nd_a_del[0,:, 0], self.nd_a[0, indices, 0]) + assert_array_equal(xor, self.nd_a[0,:, 0], err_msg=msg) def test_slices(self): lims = [-6, -2, 0, 1, 2, 4, 5] @@ -513,8 +708,19 @@ class TestDelete(TestCase): assert_(isinstance(delete(a, slice(1, 2)), SubClass)) assert_(isinstance(delete(a, slice(1, -2)), SubClass)) + def test_array_order_preserve(self): + # See gh-7113 + k = np.arange(10).reshape(2, 5, order='F') + m = delete(k, slice(60, None), axis=1) + + # 'k' is Fortran ordered, and 'm' should have the + # same ordering as 'k' and NOT become C ordered + assert_equal(m.flags.c_contiguous, k.flags.c_contiguous) + assert_equal(m.flags.f_contiguous, k.flags.f_contiguous) + class TestGradient(TestCase): + def test_basic(self): v = [[1, 1], [3, 4]] x = np.array(v) @@ -529,6 +735,9 @@ class TestGradient(TestCase): assert_raises(SyntaxError, gradient, x, np.array([1., 1.]), np.array([1., 1.]), np.array([1., 1.])) + # disallow arrays as distances, see gh-6847 + assert_raises(ValueError, gradient, np.arange(5), np.ones(5)) + def test_masked(self): # Make sure that gradient supports subclasses like masked arrays x = np.ma.array([[1, 1], [3, 4]], @@ -579,8 +788,34 @@ class TestGradient(TestCase): num_error = np.abs((np.gradient(y, dx, edge_order=2) / analytical) - 1) assert_(np.all(num_error < 0.03) == True) + def test_specific_axes(self): + # Testing that gradient can work on a given axis only + v = [[1, 1], [3, 4]] + x = np.array(v) + dx = [np.array([[2., 3.], [2., 3.]]), + np.array([[0., 0.], [1., 1.]])] + assert_array_equal(gradient(x, axis=0), dx[0]) + assert_array_equal(gradient(x, axis=1), dx[1]) + assert_array_equal(gradient(x, axis=-1), dx[1]) + assert_array_equal(gradient(x, axis=(1, 0)), [dx[1], dx[0]]) + + # test axis=None which means all axes + assert_almost_equal(gradient(x, axis=None), [dx[0], dx[1]]) + # and is the same as no axis keyword given + assert_almost_equal(gradient(x, axis=None), gradient(x)) + + # test vararg order + assert_array_equal(gradient(x, 2, 3, axis=(1, 0)), [dx[1]/2.0, dx[0]/3.0]) + # test maximal number of varargs + assert_raises(SyntaxError, gradient, x, 1, 2, axis=1) + + assert_raises(ValueError, gradient, x, axis=3) + assert_raises(ValueError, gradient, x, axis=-3) + assert_raises(TypeError, gradient, x, axis=[1,]) + class TestAngle(TestCase): + def test_basic(self): x = [1 + 3j, np.sqrt(2) / 2.0 + 1j * np.sqrt(2) / 2, 1, 1j, -1, -1j, 1 - 3j, -1 + 3j] @@ -596,8 +831,12 @@ class TestAngle(TestCase): class TestTrimZeros(TestCase): - """ only testing for integer splits. + + """ + Only testing for integer splits. + """ + def test_basic(self): a = np.array([0, 0, 1, 2, 3, 4, 0]) res = trim_zeros(a) @@ -615,16 +854,34 @@ class TestTrimZeros(TestCase): class TestExtins(TestCase): + def test_basic(self): a = np.array([1, 3, 2, 1, 2, 3, 3]) b = extract(a > 1, a) assert_array_equal(b, [3, 2, 2, 3, 3]) def test_place(self): + # Make sure that non-np.ndarray objects + # raise an error instead of doing nothing + assert_raises(TypeError, place, [1, 2, 3], [True, False], [0, 1]) + a = np.array([1, 4, 3, 2, 5, 8, 7]) place(a, [0, 1, 0, 1, 0, 1, 0], [2, 4, 6]) assert_array_equal(a, [1, 2, 3, 4, 5, 6, 7]) + place(a, np.zeros(7), []) + assert_array_equal(a, np.arange(1, 8)) + + place(a, [1, 0, 1, 0, 1, 0, 1], [8, 9]) + assert_array_equal(a, [8, 2, 9, 4, 8, 6, 9]) + assert_raises_regex(ValueError, "Cannot insert from an empty array", + lambda: place(a, [0, 0, 0, 0, 0, 1, 0], [])) + + # See Issue #6974 + a = np.array(['12', '34']) + place(a, [0, 1], '9') + assert_array_equal(a, ['12', '9']) + def test_both(self): a = rand(10) mask = a > 0.5 @@ -636,12 +893,14 @@ class TestExtins(TestCase): class TestVectorize(TestCase): + def test_simple(self): def addsubtract(a, b): if a > b: return a - b else: return a + b + f = vectorize(addsubtract) r = f([0, 3, 6, 9], [1, 3, 5, 7]) assert_array_equal(r, [1, 6, 1, 2]) @@ -652,6 +911,7 @@ class TestVectorize(TestCase): return a - b else: return a + b + f = vectorize(addsubtract) r = f([0, 3, 6, 9], 5) assert_array_equal(r, [5, 8, 1, 4]) @@ -665,16 +925,16 @@ class TestVectorize(TestCase): def test_ufunc(self): import math f = vectorize(math.cos) - args = np.array([0, 0.5*np.pi, np.pi, 1.5*np.pi, 2*np.pi]) + args = np.array([0, 0.5 * np.pi, np.pi, 1.5 * np.pi, 2 * np.pi]) r1 = f(args) r2 = np.cos(args) - assert_array_equal(r1, r2) + assert_array_almost_equal(r1, r2) def test_keywords(self): - import math def foo(a, b=1): return a + b + f = vectorize(foo) args = np.array([1, 2, 3]) r1 = f(args) @@ -690,16 +950,16 @@ class TestVectorize(TestCase): # inspect the func_code. import random try: - f = vectorize(random.randrange) + vectorize(random.randrange) # Should succeed except: raise AssertionError() def test_keywords2_ticket_2100(self): - r"""Test kwarg support: enhancement ticket 2100""" - import math + # Test kwarg support: enhancement ticket 2100 def foo(a, b=1): return a + b + f = vectorize(foo) args = np.array([1, 2, 3]) r1 = f(a=args) @@ -712,13 +972,14 @@ class TestVectorize(TestCase): assert_array_equal(r1, r2) def test_keywords3_ticket_2100(self): - """Test excluded with mixed positional and kwargs: ticket 2100""" + # Test excluded with mixed positional and kwargs: ticket 2100 def mypolyval(x, p): _p = list(p) res = _p.pop(0) while _p: - res = res*x + _p.pop(0) + res = res * x + _p.pop(0) return res + vpolyval = np.vectorize(mypolyval, excluded=['p', 1]) ans = [3, 6] assert_array_equal(ans, vpolyval(x=[0, 1], p=[1, 2, 3])) @@ -726,49 +987,58 @@ class TestVectorize(TestCase): assert_array_equal(ans, vpolyval([0, 1], [1, 2, 3])) def test_keywords4_ticket_2100(self): - """Test vectorizing function with no positional args.""" + # Test vectorizing function with no positional args. @vectorize def f(**kw): res = 1.0 for _k in kw: res *= kw[_k] return res + assert_array_equal(f(a=[1, 2], b=[3, 4]), [3, 8]) def test_keywords5_ticket_2100(self): - """Test vectorizing function with no kwargs args.""" + # Test vectorizing function with no kwargs args. @vectorize def f(*v): return np.prod(v) + assert_array_equal(f([1, 2], [3, 4]), [3, 8]) def test_coverage1_ticket_2100(self): def foo(): return 1 + f = vectorize(foo) assert_array_equal(f(), 1) def test_assigning_docstring(self): def foo(x): + """Original documentation""" return x + + f = vectorize(foo) + assert_equal(f.__doc__, foo.__doc__) + doc = "Provided documentation" f = vectorize(foo, doc=doc) assert_equal(f.__doc__, doc) def test_UnboundMethod_ticket_1156(self): - """Regression test for issue 1156""" + # Regression test for issue 1156 class Foo: b = 2 def bar(self, a): - return a**self.b + return a ** self.b + assert_array_equal(vectorize(Foo().bar)(np.arange(9)), - np.arange(9)**2) + np.arange(9) ** 2) assert_array_equal(vectorize(Foo.bar)(Foo(), np.arange(9)), - np.arange(9)**2) + np.arange(9) ** 2) def test_execution_order_ticket_1487(self): - """Regression test for dependence on execution order: issue 1487""" + # Regression test for dependence on execution order: issue 1487 f1 = vectorize(lambda x: x) res1a = f1(np.arange(3)) res1b = f1(np.arange(0.1, 3)) @@ -779,24 +1049,23 @@ class TestVectorize(TestCase): assert_equal(res1b, res2b) def test_string_ticket_1892(self): - """Test vectorization over strings: issue 1892.""" + # Test vectorization over strings: issue 1892. f = np.vectorize(lambda x: x) - s = '0123456789'*10 + s = '0123456789' * 10 assert_equal(s, f(s)) - #z = f(np.array([s,s])) - #assert_array_equal([s,s], f(s)) def test_cache(self): - """Ensure that vectorized func called exactly once per argument.""" + # Ensure that vectorized func called exactly once per argument. _calls = [0] @vectorize def f(x): _calls[0] += 1 - return x**2 + return x ** 2 + f.cache = True x = np.arange(5) - assert_array_equal(f(x), x*x) + assert_array_equal(f(x), x * x) assert_equal(_calls[0], len(x)) def test_otypes(self): @@ -805,8 +1074,158 @@ class TestVectorize(TestCase): x = np.arange(5) assert_array_equal(f(x), x) + def test_parse_gufunc_signature(self): + assert_equal(nfb._parse_gufunc_signature('(x)->()'), ([('x',)], [()])) + assert_equal(nfb._parse_gufunc_signature('(x,y)->()'), + ([('x', 'y')], [()])) + assert_equal(nfb._parse_gufunc_signature('(x),(y)->()'), + ([('x',), ('y',)], [()])) + assert_equal(nfb._parse_gufunc_signature('(x)->(y)'), + ([('x',)], [('y',)])) + assert_equal(nfb._parse_gufunc_signature('(x)->(y),()'), + ([('x',)], [('y',), ()])) + assert_equal(nfb._parse_gufunc_signature('(),(a,b,c),(d)->(d,e)'), + ([(), ('a', 'b', 'c'), ('d',)], [('d', 'e')])) + with assert_raises(ValueError): + nfb._parse_gufunc_signature('(x)(y)->()') + with assert_raises(ValueError): + nfb._parse_gufunc_signature('(x),(y)->') + with assert_raises(ValueError): + nfb._parse_gufunc_signature('((x))->(x)') + + def test_signature_simple(self): + def addsubtract(a, b): + if a > b: + return a - b + else: + return a + b + + f = vectorize(addsubtract, signature='(),()->()') + r = f([0, 3, 6, 9], [1, 3, 5, 7]) + assert_array_equal(r, [1, 6, 1, 2]) + + def test_signature_mean_last(self): + def mean(a): + return a.mean() + + f = vectorize(mean, signature='(n)->()') + r = f([[1, 3], [2, 4]]) + assert_array_equal(r, [2, 3]) + + def test_signature_center(self): + def center(a): + return a - a.mean() + + f = vectorize(center, signature='(n)->(n)') + r = f([[1, 3], [2, 4]]) + assert_array_equal(r, [[-1, 1], [-1, 1]]) + + def test_signature_two_outputs(self): + f = vectorize(lambda x: (x, x), signature='()->(),()') + r = f([1, 2, 3]) + assert_(isinstance(r, tuple) and len(r) == 2) + assert_array_equal(r[0], [1, 2, 3]) + assert_array_equal(r[1], [1, 2, 3]) + + def test_signature_outer(self): + f = vectorize(np.outer, signature='(a),(b)->(a,b)') + r = f([1, 2], [1, 2, 3]) + assert_array_equal(r, [[1, 2, 3], [2, 4, 6]]) + + r = f([[[1, 2]]], [1, 2, 3]) + assert_array_equal(r, [[[[1, 2, 3], [2, 4, 6]]]]) + + r = f([[1, 0], [2, 0]], [1, 2, 3]) + assert_array_equal(r, [[[1, 2, 3], [0, 0, 0]], + [[2, 4, 6], [0, 0, 0]]]) + + r = f([1, 2], [[1, 2, 3], [0, 0, 0]]) + assert_array_equal(r, [[[1, 2, 3], [2, 4, 6]], + [[0, 0, 0], [0, 0, 0]]]) + + def test_signature_computed_size(self): + f = vectorize(lambda x: x[:-1], signature='(n)->(m)') + r = f([1, 2, 3]) + assert_array_equal(r, [1, 2]) + + r = f([[1, 2, 3], [2, 3, 4]]) + assert_array_equal(r, [[1, 2], [2, 3]]) + + def test_signature_excluded(self): + + def foo(a, b=1): + return a + b + + f = vectorize(foo, signature='()->()', excluded={'b'}) + assert_array_equal(f([1, 2, 3]), [2, 3, 4]) + assert_array_equal(f([1, 2, 3], b=0), [1, 2, 3]) + + def test_signature_otypes(self): + f = vectorize(lambda x: x, signature='(n)->(n)', otypes=['float64']) + r = f([1, 2, 3]) + assert_equal(r.dtype, np.dtype('float64')) + assert_array_equal(r, [1, 2, 3]) + + def test_signature_invalid_inputs(self): + f = vectorize(operator.add, signature='(n),(n)->(n)') + with assert_raises_regex(TypeError, 'wrong number of positional'): + f([1, 2]) + with assert_raises_regex( + ValueError, 'does not have enough dimensions'): + f(1, 2) + with assert_raises_regex( + ValueError, 'inconsistent size for core dimension'): + f([1, 2], [1, 2, 3]) + + f = vectorize(operator.add, signature='()->()') + with assert_raises_regex(TypeError, 'wrong number of positional'): + f(1, 2) + + def test_signature_invalid_outputs(self): + + f = vectorize(lambda x: x[:-1], signature='(n)->(n)') + with assert_raises_regex( + ValueError, 'inconsistent size for core dimension'): + f([1, 2, 3]) + + f = vectorize(lambda x: x, signature='()->(),()') + with assert_raises_regex(ValueError, 'wrong number of outputs'): + f(1) + + f = vectorize(lambda x: (x, x), signature='()->()') + with assert_raises_regex(ValueError, 'wrong number of outputs'): + f([1, 2]) + + def test_size_zero_output(self): + # see issue 5868 + f = np.vectorize(lambda x: x) + x = np.zeros([0, 5], dtype=int) + with assert_raises_regex(ValueError, 'otypes'): + f(x) + + f.otypes = 'i' + assert_array_equal(f(x), x) + + f = np.vectorize(lambda x: x, signature='()->()') + with assert_raises_regex(ValueError, 'otypes'): + f(x) + + f = np.vectorize(lambda x: x, signature='()->()', otypes='i') + assert_array_equal(f(x), x) + + f = np.vectorize(lambda x: x, signature='(n)->(n)', otypes='i') + assert_array_equal(f(x), x) + + f = np.vectorize(lambda x: x, signature='(n)->(n)') + assert_array_equal(f(x.T), x.T) + + f = np.vectorize(lambda x: [x], signature='()->(n)', otypes='i') + with assert_raises_regex(ValueError, 'new output dimensions'): + f(x) + class TestDigitize(TestCase): + def test_forward(self): x = np.arange(-6, 5) bins = np.arange(-5, 5) @@ -861,50 +1280,69 @@ class TestDigitize(TestCase): bins = [1, 1, 0, 1] assert_raises(ValueError, digitize, x, bins) + def test_casting_error(self): + x = [1, 2, 3 + 1.j] + bins = [1, 2, 3] + assert_raises(TypeError, digitize, x, bins) + x, bins = bins, x + assert_raises(TypeError, digitize, x, bins) + + def test_return_type(self): + # Functions returning indices should always return base ndarrays + class A(np.ndarray): + pass + a = np.arange(5).view(A) + b = np.arange(1, 3).view(A) + assert_(not isinstance(digitize(b, a, False), A)) + assert_(not isinstance(digitize(b, a, True), A)) + class TestUnwrap(TestCase): + def test_simple(self): - #check that unwrap removes jumps greather that 2*pi + # check that unwrap removes jumps greather that 2*pi assert_array_equal(unwrap([1, 1 + 2 * np.pi]), [1, 1]) - #check that unwrap maintans continuity + # check that unwrap maintans continuity assert_(np.all(diff(unwrap(rand(10) * 100)) < np.pi)) class TestFilterwindows(TestCase): + def test_hanning(self): - #check symmetry + # check symmetry w = hanning(10) assert_array_almost_equal(w, flipud(w), 7) - #check known value + # check known value assert_almost_equal(np.sum(w, axis=0), 4.500, 4) def test_hamming(self): - #check symmetry + # check symmetry w = hamming(10) assert_array_almost_equal(w, flipud(w), 7) - #check known value + # check known value assert_almost_equal(np.sum(w, axis=0), 4.9400, 4) def test_bartlett(self): - #check symmetry + # check symmetry w = bartlett(10) assert_array_almost_equal(w, flipud(w), 7) - #check known value + # check known value assert_almost_equal(np.sum(w, axis=0), 4.4444, 4) def test_blackman(self): - #check symmetry + # check symmetry w = blackman(10) assert_array_almost_equal(w, flipud(w), 7) - #check known value + # check known value assert_almost_equal(np.sum(w, axis=0), 3.7800, 4) class TestTrapz(TestCase): + def test_simple(self): x = np.arange(-10, 10, .1) - r = trapz(np.exp(-.5*x**2) / np.sqrt(2*np.pi), dx=0.1) - #check integral of normal equals 1 + r = trapz(np.exp(-.5 * x ** 2) / np.sqrt(2 * np.pi), dx=0.1) + # check integral of normal equals 1 assert_almost_equal(r, 1, 7) def test_ndim(self): @@ -922,7 +1360,7 @@ class TestTrapz(TestCase): wz[0] /= 2 wz[-1] /= 2 - q = x[:, None, None] + y[None, :, None] + z[None, None, :] + q = x[:, None, None] + y[None,:, None] + z[None, None,:] qx = (q * wx[:, None, None]).sum(axis=0) qy = (q * wy[None, :, None]).sum(axis=1) @@ -931,9 +1369,9 @@ class TestTrapz(TestCase): # n-d `x` r = trapz(q, x=x[:, None, None], axis=0) assert_almost_equal(r, qx) - r = trapz(q, x=y[None, :, None], axis=1) + r = trapz(q, x=y[None,:, None], axis=1) assert_almost_equal(r, qy) - r = trapz(q, x=z[None, None, :], axis=2) + r = trapz(q, x=z[None, None,:], axis=2) assert_almost_equal(r, qz) # 1-d `x` @@ -945,8 +1383,8 @@ class TestTrapz(TestCase): assert_almost_equal(r, qz) def test_masked(self): - #Testing that masked arrays behave as if the function is 0 where - #masked + # Testing that masked arrays behave as if the function is 0 where + # masked x = np.arange(5) y = x * x mask = x == 2 @@ -961,7 +1399,7 @@ class TestTrapz(TestCase): assert_almost_equal(trapz(y, xm), r) def test_matrix(self): - #Test to make sure matrices give the same answer as ndarrays + # Test to make sure matrices give the same answer as ndarrays x = np.linspace(0, 5) y = x * x r = trapz(y, x) @@ -972,10 +1410,11 @@ class TestTrapz(TestCase): class TestSinc(TestCase): + def test_simple(self): assert_(sinc(0) == 1) w = sinc(np.linspace(-1, 1, 100)) - #check symmetry + # check symmetry assert_array_almost_equal(w, flipud(w), 7) def test_array_like(self): @@ -988,6 +1427,7 @@ class TestSinc(TestCase): class TestHistogram(TestCase): + def setUp(self): pass @@ -998,10 +1438,10 @@ class TestHistogram(TestCase): n = 100 v = rand(n) (a, b) = histogram(v) - #check if the sum of the bins equals the number of samples + # check if the sum of the bins equals the number of samples assert_equal(np.sum(a, axis=0), n) - #check that the bin counts are evenly spaced when the data is from a - # linear function + # check that the bin counts are evenly spaced when the data is from + # a linear function (a, b) = histogram(np.linspace(0, 10, 100)) assert_array_equal(a, 10) @@ -1023,7 +1463,8 @@ class TestHistogram(TestCase): area = np.sum(a * diff(b)) assert_almost_equal(area, 1) - # Check with non-constant bin widths (buggy but backwards compatible) + # Check with non-constant bin widths (buggy but backwards + # compatible) v = np.arange(10) bins = [0, 1, 5, 9, 10] a, b = histogram(v, bins, normed=True) @@ -1043,7 +1484,7 @@ class TestHistogram(TestCase): bins = [0, 1, 3, 6, 10] a, b = histogram(v, bins, density=True) assert_array_equal(a, .1) - assert_equal(np.sum(a*diff(b)), 1) + assert_equal(np.sum(a * diff(b)), 1) # Variale bin widths are especially useful to deal with # infinities. @@ -1086,20 +1527,20 @@ class TestHistogram(TestCase): # Check the type of the returned histogram a = np.arange(10) + .5 h, b = histogram(a) - assert_(issubdtype(h.dtype, int)) + assert_(np.issubdtype(h.dtype, int)) h, b = histogram(a, normed=True) - assert_(issubdtype(h.dtype, float)) + assert_(np.issubdtype(h.dtype, float)) h, b = histogram(a, weights=np.ones(10, int)) - assert_(issubdtype(h.dtype, int)) + assert_(np.issubdtype(h.dtype, int)) h, b = histogram(a, weights=np.ones(10, float)) - assert_(issubdtype(h.dtype, float)) + assert_(np.issubdtype(h.dtype, float)) def test_f32_rounding(self): # gh-4799, check that the rounding of the edges works with float32 - x = np.array([276.318359 , -69.593948 , 21.329449], dtype=np.float32) + x = np.array([276.318359, -69.593948, 21.329449], dtype=np.float32) y = np.array([5005.689453, 4481.327637, 6010.369629], dtype=np.float32) counts_hist, xedges, yedges = np.histogram2d(x, y, bins=100) assert_equal(counts_hist.sum(), 3.) @@ -1133,13 +1574,215 @@ class TestHistogram(TestCase): weights=[2, 1, 1, 1, 1, 1, 1, 1, 1], density=True) assert_almost_equal(a, [.2, .1, .1, .075]) + def test_exotic_weights(self): + + # Test the use of weights that are not integer or floats, but e.g. + # complex numbers or object types. + + # Complex weights + values = np.array([1.3, 2.5, 2.3]) + weights = np.array([1, -1, 2]) + 1j * np.array([2, 1, 2]) + + # Check with custom bins + wa, wb = histogram(values, bins=[0, 2, 3], weights=weights) + assert_array_almost_equal(wa, np.array([1, 1]) + 1j * np.array([2, 3])) + + # Check with even bins + wa, wb = histogram(values, bins=2, range=[1, 3], weights=weights) + assert_array_almost_equal(wa, np.array([1, 1]) + 1j * np.array([2, 3])) + + # Decimal weights + from decimal import Decimal + values = np.array([1.3, 2.5, 2.3]) + weights = np.array([Decimal(1), Decimal(2), Decimal(3)]) + + # Check with custom bins + wa, wb = histogram(values, bins=[0, 2, 3], weights=weights) + assert_array_almost_equal(wa, [Decimal(1), Decimal(5)]) + + # Check with even bins + wa, wb = histogram(values, bins=2, range=[1, 3], weights=weights) + assert_array_almost_equal(wa, [Decimal(1), Decimal(5)]) + + def test_no_side_effects(self): + # This is a regression test that ensures that values passed to + # ``histogram`` are unchanged. + values = np.array([1.3, 2.5, 2.3]) + np.histogram(values, range=[-10, 10], bins=100) + assert_array_almost_equal(values, [1.3, 2.5, 2.3]) + def test_empty(self): a, b = histogram([], bins=([0, 1])) assert_array_equal(a, np.array([0])) assert_array_equal(b, np.array([0, 1])) + def test_error_binnum_type (self): + # Tests if right Error is raised if bins argument is float + vals = np.linspace(0.0, 1.0, num=100) + histogram(vals, 5) + assert_raises(TypeError, histogram, vals, 2.4) + + def test_finite_range(self): + # Normal ranges should be fine + vals = np.linspace(0.0, 1.0, num=100) + histogram(vals, range=[0.25,0.75]) + assert_raises(ValueError, histogram, vals, range=[np.nan,0.75]) + assert_raises(ValueError, histogram, vals, range=[0.25,np.inf]) + + def test_bin_edge_cases(self): + # Ensure that floating-point computations correctly place edge cases. + arr = np.array([337, 404, 739, 806, 1007, 1811, 2012]) + hist, edges = np.histogram(arr, bins=8296, range=(2, 2280)) + mask = hist > 0 + left_edges = edges[:-1][mask] + right_edges = edges[1:][mask] + for x, left, right in zip(arr, left_edges, right_edges): + self.assertGreaterEqual(x, left) + self.assertLess(x, right) + + def test_last_bin_inclusive_range(self): + arr = np.array([0., 0., 0., 1., 2., 3., 3., 4., 5.]) + hist, edges = np.histogram(arr, bins=30, range=(-0.5, 5)) + self.assertEqual(hist[-1], 1) + + +class TestHistogramOptimBinNums(TestCase): + """ + Provide test coverage when using provided estimators for optimal number of + bins + """ + + def test_empty(self): + estimator_list = ['fd', 'scott', 'rice', 'sturges', + 'doane', 'sqrt', 'auto'] + # check it can deal with empty data + for estimator in estimator_list: + a, b = histogram([], bins=estimator) + assert_array_equal(a, np.array([0])) + assert_array_equal(b, np.array([0, 1])) + + def test_simple(self): + """ + Straightforward testing with a mixture of linspace data (for + consistency). All test values have been precomputed and the values + shouldn't change + """ + # Some basic sanity checking, with some fixed data. + # Checking for the correct number of bins + basic_test = {50: {'fd': 4, 'scott': 4, 'rice': 8, 'sturges': 7, + 'doane': 8, 'sqrt': 8, 'auto': 7}, + 500: {'fd': 8, 'scott': 8, 'rice': 16, 'sturges': 10, + 'doane': 12, 'sqrt': 23, 'auto': 10}, + 5000: {'fd': 17, 'scott': 17, 'rice': 35, 'sturges': 14, + 'doane': 17, 'sqrt': 71, 'auto': 17}} + + for testlen, expectedResults in basic_test.items(): + # Create some sort of non uniform data to test with + # (2 peak uniform mixture) + x1 = np.linspace(-10, -1, testlen // 5 * 2) + x2 = np.linspace(1, 10, testlen // 5 * 3) + x = np.concatenate((x1, x2)) + for estimator, numbins in expectedResults.items(): + a, b = np.histogram(x, estimator) + assert_equal(len(a), numbins, err_msg="For the {0} estimator " + "with datasize of {1}".format(estimator, testlen)) + + def test_small(self): + """ + Smaller datasets have the potential to cause issues with the data + adaptive methods, especially the FD method. All bin numbers have been + precalculated. + """ + small_dat = {1: {'fd': 1, 'scott': 1, 'rice': 1, 'sturges': 1, + 'doane': 1, 'sqrt': 1}, + 2: {'fd': 2, 'scott': 1, 'rice': 3, 'sturges': 2, + 'doane': 1, 'sqrt': 2}, + 3: {'fd': 2, 'scott': 2, 'rice': 3, 'sturges': 3, + 'doane': 3, 'sqrt': 2}} + + for testlen, expectedResults in small_dat.items(): + testdat = np.arange(testlen) + for estimator, expbins in expectedResults.items(): + a, b = np.histogram(testdat, estimator) + assert_equal(len(a), expbins, err_msg="For the {0} estimator " + "with datasize of {1}".format(estimator, testlen)) + + def test_incorrect_methods(self): + """ + Check a Value Error is thrown when an unknown string is passed in + """ + check_list = ['mad', 'freeman', 'histograms', 'IQR'] + for estimator in check_list: + assert_raises(ValueError, histogram, [1, 2, 3], estimator) + + def test_novariance(self): + """ + Check that methods handle no variance in data + Primarily for Scott and FD as the SD and IQR are both 0 in this case + """ + novar_dataset = np.ones(100) + novar_resultdict = {'fd': 1, 'scott': 1, 'rice': 1, 'sturges': 1, + 'doane': 1, 'sqrt': 1, 'auto': 1} + + for estimator, numbins in novar_resultdict.items(): + a, b = np.histogram(novar_dataset, estimator) + assert_equal(len(a), numbins, err_msg="{0} estimator, " + "No Variance test".format(estimator)) + + def test_outlier(self): + """ + Check the FD, Scott and Doane with outliers. + + The FD estimates a smaller binwidth since it's less affected by + outliers. Since the range is so (artificially) large, this means more + bins, most of which will be empty, but the data of interest usually is + unaffected. The Scott estimator is more affected and returns fewer bins, + despite most of the variance being in one area of the data. The Doane + estimator lies somewhere between the other two. + """ + xcenter = np.linspace(-10, 10, 50) + outlier_dataset = np.hstack((np.linspace(-110, -100, 5), xcenter)) + + outlier_resultdict = {'fd': 21, 'scott': 5, 'doane': 11} + + for estimator, numbins in outlier_resultdict.items(): + a, b = np.histogram(outlier_dataset, estimator) + assert_equal(len(a), numbins) + + def test_simple_range(self): + """ + Straightforward testing with a mixture of linspace data (for + consistency). Adding in a 3rd mixture that will then be + completely ignored. All test values have been precomputed and + the shouldn't change. + """ + # some basic sanity checking, with some fixed data. Checking for the correct number of bins + basic_test = {50: {'fd': 8, 'scott': 8, 'rice': 15, 'sturges': 14, 'auto': 14}, + 500: {'fd': 15, 'scott': 16, 'rice': 32, 'sturges': 20, 'auto': 20}, + 5000: {'fd': 33, 'scott': 33, 'rice': 69, 'sturges': 27, 'auto': 33}} + + for testlen, expectedResults in basic_test.items(): + # create some sort of non uniform data to test with (3 peak uniform mixture) + x1 = np.linspace(-10, -1, testlen // 5 * 2) + x2 = np.linspace(1, 10, testlen // 5 * 3) + x3 = np.linspace(-100, -50, testlen) + x = np.hstack((x1, x2, x3)) + for estimator, numbins in expectedResults.items(): + a, b = np.histogram(x, estimator, range = (-20, 20)) + msg = "For the {0} estimator with datasize of {1}".format(estimator, testlen) + assert_equal(len(a), numbins, err_msg=msg) + + def test_simple_weighted(self): + """ + Check that weighted data raises a TypeError + """ + estimator_list = ['fd', 'scott', 'rice', 'sturges', 'auto'] + for estimator in estimator_list: + assert_raises(TypeError, histogram, [1, 2, 3], estimator, weights=[1, 2, 3]) + class TestHistogramdd(TestCase): + def test_simple(self): x = np.array([[-.5, .5, 1.5], [-.5, 1.5, 2.5], [-.5, 2.5, .5], [.5, .5, 1.5], [.5, 1.5, 2.5], [.5, 2.5, 2.5]]) @@ -1223,8 +1866,8 @@ class TestHistogramdd(TestCase): assert_array_max_ulp(a, np.zeros((2, 2, 2))) def test_bins_errors(self): - """There are two ways to specify bins. Check for the right errors when - mixing those.""" + # There are two ways to specify bins. Check for the right errors + # when mixing those. x = np.arange(8).reshape(2, 4) assert_raises(ValueError, np.histogramdd, x, bins=[-1, 2, 4, 5]) assert_raises(ValueError, np.histogramdd, x, bins=[1, 0.99, 1, 1]) @@ -1235,7 +1878,7 @@ class TestHistogramdd(TestCase): assert_(np.histogramdd(x, bins=[1, 1, 1, [1, 2, 3, 4]])) def test_inf_edges(self): - """Test using +/-inf bin edges works. See #1788.""" + # Test using +/-inf bin edges works. See #1788. with np.errstate(invalid='ignore'): x = np.arange(6).reshape(3, 2) expected = np.array([[1, 0], [0, 1], [0, 1]]) @@ -1247,31 +1890,39 @@ class TestHistogramdd(TestCase): assert_allclose(h, expected) def test_rightmost_binedge(self): - """Test event very close to rightmost binedge. - See Github issue #4266""" + # Test event very close to rightmost binedge. See Github issue #4266 x = [0.9999999995] - bins = [[0.,0.5,1.0]] + bins = [[0., 0.5, 1.0]] hist, _ = histogramdd(x, bins=bins) assert_(hist[0] == 0.0) assert_(hist[1] == 1.) x = [1.0] - bins = [[0.,0.5,1.0]] + bins = [[0., 0.5, 1.0]] hist, _ = histogramdd(x, bins=bins) assert_(hist[0] == 0.0) assert_(hist[1] == 1.) x = [1.0000000001] - bins = [[0.,0.5,1.0]] + bins = [[0., 0.5, 1.0]] hist, _ = histogramdd(x, bins=bins) assert_(hist[0] == 0.0) assert_(hist[1] == 1.) x = [1.0001] - bins = [[0.,0.5,1.0]] + bins = [[0., 0.5, 1.0]] hist, _ = histogramdd(x, bins=bins) assert_(hist[0] == 0.0) assert_(hist[1] == 0.0) + def test_finite_range(self): + vals = np.random.random((100, 3)) + histogramdd(vals, range=[[0.0, 1.0], [0.25, 0.75], [0.25, 0.5]]) + assert_raises(ValueError, histogramdd, vals, + range=[[0.0, 1.0], [0.25, 0.75], [0.25, np.inf]]) + assert_raises(ValueError, histogramdd, vals, + range=[[0.0, 1.0], [np.nan, 0.75], [0.25, 0.5]]) + class TestUnique(TestCase): + def test_simple(self): x = np.array([4, 3, 2, 1, 1, 2, 3, 4, 0]) assert_(np.all(unique(x) == [0, 1, 2, 3, 4])) @@ -1283,6 +1934,7 @@ class TestUnique(TestCase): class TestCheckFinite(TestCase): + def test_simple(self): a = [1, 2, 3] b = [1, 2, np.inf] @@ -1292,7 +1944,7 @@ class TestCheckFinite(TestCase): assert_raises(ValueError, np.lib.asarray_chkfinite, c) def test_dtype_order(self): - """Regression test for missing dtype and order arguments""" + # Regression test for missing dtype and order arguments a = [1, 2, 3] a = np.lib.asarray_chkfinite(a, order='F', dtype=np.float64) assert_(a.dtype == np.float64) @@ -1324,16 +1976,42 @@ class TestCorrCoef(TestCase): [[1., -1.], [-1., 1.]]) def test_simple(self): - assert_almost_equal(corrcoef(self.A), self.res1) - assert_almost_equal(corrcoef(self.A, self.B), self.res2) + tgt1 = corrcoef(self.A) + assert_almost_equal(tgt1, self.res1) + assert_(np.all(np.abs(tgt1) <= 1.0)) + + tgt2 = corrcoef(self.A, self.B) + assert_almost_equal(tgt2, self.res2) + assert_(np.all(np.abs(tgt2) <= 1.0)) def test_ddof(self): - assert_almost_equal(corrcoef(self.A, ddof=-1), self.res1) - assert_almost_equal(corrcoef(self.A, self.B, ddof=-1), self.res2) + # ddof raises DeprecationWarning + with suppress_warnings() as sup: + warnings.simplefilter("always") + assert_warns(DeprecationWarning, corrcoef, self.A, ddof=-1) + sup.filter(DeprecationWarning) + # ddof has no or negligible effect on the function + assert_almost_equal(corrcoef(self.A, ddof=-1), self.res1) + assert_almost_equal(corrcoef(self.A, self.B, ddof=-1), self.res2) + assert_almost_equal(corrcoef(self.A, ddof=3), self.res1) + assert_almost_equal(corrcoef(self.A, self.B, ddof=3), self.res2) + + def test_bias(self): + # bias raises DeprecationWarning + with suppress_warnings() as sup: + warnings.simplefilter("always") + assert_warns(DeprecationWarning, corrcoef, self.A, self.B, 1, 0) + assert_warns(DeprecationWarning, corrcoef, self.A, bias=0) + sup.filter(DeprecationWarning) + # bias has no or negligible effect on the function + assert_almost_equal(corrcoef(self.A, bias=1), self.res1) def test_complex(self): x = np.array([[1, 2, 3], [1j, 2j, 3j]]) - assert_allclose(corrcoef(x), np.array([[1., -1.j], [1.j, 1.]])) + res = corrcoef(x) + tgt = np.array([[1., -1.j], [1.j, 1.]]) + assert_allclose(res, tgt) + assert_(np.all(np.abs(res) <= 1.0)) def test_xy(self): x = np.array([[1, 2, 3]]) @@ -1349,18 +2027,29 @@ class TestCorrCoef(TestCase): assert_array_equal(corrcoef(np.array([]).reshape(2, 0)), np.array([[np.nan, np.nan], [np.nan, np.nan]])) - def test_wrong_ddof(self): - x = np.array([[0, 2], [1, 1], [2, 0]]).T - with warnings.catch_warnings(record=True): - warnings.simplefilter('always', RuntimeWarning) - assert_array_equal(corrcoef(x, ddof=5), - np.array([[np.nan, np.nan], [np.nan, np.nan]])) + def test_extreme(self): + x = [[1e-100, 1e100], [1e100, 1e-100]] + with np.errstate(all='raise'): + c = corrcoef(x) + assert_array_almost_equal(c, np.array([[1., -1.], [-1., 1.]])) + assert_(np.all(np.abs(c) <= 1.0)) class TestCov(TestCase): + x1 = np.array([[0, 2], [1, 1], [2, 0]]).T + res1 = np.array([[1., -1.], [-1., 1.]]) + x2 = np.array([0.0, 1.0, 2.0], ndmin=2) + frequencies = np.array([1, 4, 1]) + x2_repeats = np.array([[0.0], [1.0], [1.0], [1.0], [1.0], [2.0]]).T + res2 = np.array([[0.4, -0.4], [-0.4, 0.4]]) + unit_frequencies = np.ones(3, dtype=np.integer) + weights = np.array([1.0, 4.0, 1.0]) + res3 = np.array([[2. / 3., -2. / 3.], [-2. / 3., 2. / 3.]]) + unit_weights = np.ones(3) + x3 = np.array([0.3942, 0.5969, 0.7730, 0.9918, 0.7964]) + def test_basic(self): - x = np.array([[0, 2], [1, 1], [2, 0]]).T - assert_allclose(cov(x), np.array([[1., -1.], [-1., 1.]])) + assert_allclose(cov(self.x1), self.res1) def test_complex(self): x = np.array([[1, 2, 3], [1j, 2j, 3j]]) @@ -1381,14 +2070,71 @@ class TestCov(TestCase): np.array([[np.nan, np.nan], [np.nan, np.nan]])) def test_wrong_ddof(self): - x = np.array([[0, 2], [1, 1], [2, 0]]).T with warnings.catch_warnings(record=True): warnings.simplefilter('always', RuntimeWarning) - assert_array_equal(cov(x, ddof=5), - np.array([[np.inf, -np.inf], [-np.inf, np.inf]])) + assert_array_equal(cov(self.x1, ddof=5), + np.array([[np.inf, -np.inf], + [-np.inf, np.inf]])) + + def test_1D_rowvar(self): + assert_allclose(cov(self.x3), cov(self.x3, rowvar=0)) + y = np.array([0.0780, 0.3107, 0.2111, 0.0334, 0.8501]) + assert_allclose(cov(self.x3, y), cov(self.x3, y, rowvar=0)) + + def test_1D_variance(self): + assert_allclose(cov(self.x3, ddof=1), np.var(self.x3, ddof=1)) + + def test_fweights(self): + assert_allclose(cov(self.x2, fweights=self.frequencies), + cov(self.x2_repeats)) + assert_allclose(cov(self.x1, fweights=self.frequencies), + self.res2) + assert_allclose(cov(self.x1, fweights=self.unit_frequencies), + self.res1) + nonint = self.frequencies + 0.5 + assert_raises(TypeError, cov, self.x1, fweights=nonint) + f = np.ones((2, 3), dtype=np.integer) + assert_raises(RuntimeError, cov, self.x1, fweights=f) + f = np.ones(2, dtype=np.integer) + assert_raises(RuntimeError, cov, self.x1, fweights=f) + f = -1 * np.ones(3, dtype=np.integer) + assert_raises(ValueError, cov, self.x1, fweights=f) + + def test_aweights(self): + assert_allclose(cov(self.x1, aweights=self.weights), self.res3) + assert_allclose(cov(self.x1, aweights=3.0 * self.weights), + cov(self.x1, aweights=self.weights)) + assert_allclose(cov(self.x1, aweights=self.unit_weights), self.res1) + w = np.ones((2, 3)) + assert_raises(RuntimeError, cov, self.x1, aweights=w) + w = np.ones(2) + assert_raises(RuntimeError, cov, self.x1, aweights=w) + w = -1.0 * np.ones(3) + assert_raises(ValueError, cov, self.x1, aweights=w) + + def test_unit_fweights_and_aweights(self): + assert_allclose(cov(self.x2, fweights=self.frequencies, + aweights=self.unit_weights), + cov(self.x2_repeats)) + assert_allclose(cov(self.x1, fweights=self.frequencies, + aweights=self.unit_weights), + self.res2) + assert_allclose(cov(self.x1, fweights=self.unit_frequencies, + aweights=self.unit_weights), + self.res1) + assert_allclose(cov(self.x1, fweights=self.unit_frequencies, + aweights=self.weights), + self.res3) + assert_allclose(cov(self.x1, fweights=self.unit_frequencies, + aweights=3.0 * self.weights), + cov(self.x1, aweights=self.weights)) + assert_allclose(cov(self.x1, fweights=self.unit_frequencies, + aweights=self.unit_weights), + self.res1) class Test_I0(TestCase): + def test_simple(self): assert_almost_equal( i0(0.5), @@ -1414,6 +2160,7 @@ class Test_I0(TestCase): class TestKaiser(TestCase): + def test_simple(self): assert_(np.isfinite(kaiser(1, 1.0))) assert_almost_equal(kaiser(0, 1.0), @@ -1432,6 +2179,7 @@ class TestKaiser(TestCase): class TestMsort(TestCase): + def test_simple(self): A = np.array([[0.44567325, 0.79115165, 0.54900530], [0.36844147, 0.37325583, 0.96098397], @@ -1444,6 +2192,7 @@ class TestMsort(TestCase): class TestMeshgrid(TestCase): + def test_simple(self): [X, Y] = meshgrid([1, 2, 3], [4, 5, 6, 7]) assert_array_equal(X, np.array([[1, 2, 3], @@ -1522,6 +2271,7 @@ class TestMeshgrid(TestCase): class TestPiecewise(TestCase): + def test_simple(self): # Condition is single bool list x = piecewise([0, 0], [True, False], [1]) @@ -1550,6 +2300,10 @@ class TestPiecewise(TestCase): x = piecewise([1, 2], [[True, False], [False, True]], [3, 4]) assert_array_equal(x, [3, 4]) + def test_scalar_domains_three_conditions(self): + x = piecewise(3, [True, False, False], [4, 2, 0]) + assert_equal(x, 4) + def test_default(self): # No value specified for x[1], should be 0 x = piecewise([1, 2], [True, False], [2]) @@ -1572,10 +2326,18 @@ class TestPiecewise(TestCase): def test_0d_comparison(self): x = 3 - y = piecewise(x, [x <= 3, x > 3], [4, 0]) + piecewise(x, [x <= 3, x > 3], [4, 0]) # Should succeed. + + def test_multidimensional_extrafunc(self): + x = np.array([[-2.5, -1.5, -0.5], + [0.5, 1.5, 2.5]]) + y = piecewise(x, [x < 0, x >= 2], [-1, 1, 3]) + assert_array_equal(y, np.array([[-1., -1., -1.], + [3., 3., 1.]])) class TestBincount(TestCase): + def test_simple(self): y = np.bincount(np.arange(4)) assert_array_equal(y, np.ones(4)) @@ -1624,23 +2386,46 @@ class TestBincount(TestCase): def test_with_incorrect_minlength(self): x = np.array([], dtype=int) - assert_raises_regex(TypeError, "an integer is required", + assert_raises_regex(TypeError, + "'str' object cannot be interpreted", lambda: np.bincount(x, minlength="foobar")) - assert_raises_regex(ValueError, "must be positive", + assert_raises_regex(ValueError, + "must be positive", lambda: np.bincount(x, minlength=-1)) - assert_raises_regex(ValueError, "must be positive", + assert_raises_regex(ValueError, + "must be positive", lambda: np.bincount(x, minlength=0)) x = np.arange(5) - assert_raises_regex(TypeError, "an integer is required", + assert_raises_regex(TypeError, + "'str' object cannot be interpreted", lambda: np.bincount(x, minlength="foobar")) - assert_raises_regex(ValueError, "minlength must be positive", + assert_raises_regex(ValueError, + "minlength must be positive", lambda: np.bincount(x, minlength=-1)) - assert_raises_regex(ValueError, "minlength must be positive", + assert_raises_regex(ValueError, + "minlength must be positive", lambda: np.bincount(x, minlength=0)) + @dec.skipif(not HAS_REFCOUNT, "python has no sys.getrefcount") + def test_dtype_reference_leaks(self): + # gh-6805 + intp_refcount = sys.getrefcount(np.dtype(np.intp)) + double_refcount = sys.getrefcount(np.dtype(np.double)) + + for j in range(10): + np.bincount([1, 2, 3]) + assert_equal(sys.getrefcount(np.dtype(np.intp)), intp_refcount) + assert_equal(sys.getrefcount(np.dtype(np.double)), double_refcount) + + for j in range(10): + np.bincount([1, 2, 3], [4, 5, 6]) + assert_equal(sys.getrefcount(np.dtype(np.intp)), intp_refcount) + assert_equal(sys.getrefcount(np.dtype(np.double)), double_refcount) + class TestInterp(TestCase): + def test_exceptions(self): assert_raises(ValueError, interp, 0, [], []) assert_raises(ValueError, interp, 0, [0], [1, 2]) @@ -1655,10 +2440,42 @@ class TestInterp(TestCase): assert_almost_equal(np.interp(x0, x, y), x0) def test_right_left_behavior(self): - assert_equal(interp([-1, 0, 1], [0], [1]), [1, 1, 1]) - assert_equal(interp([-1, 0, 1], [0], [1], left=0), [0, 1, 1]) - assert_equal(interp([-1, 0, 1], [0], [1], right=0), [1, 1, 0]) - assert_equal(interp([-1, 0, 1], [0], [1], left=0, right=0), [0, 1, 0]) + # Needs range of sizes to test different code paths. + # size ==1 is special cased, 1 < size < 5 is linear search, and + # size >= 5 goes through local search and possibly binary search. + for size in range(1, 10): + xp = np.arange(size, dtype=np.double) + yp = np.ones(size, dtype=np.double) + incpts = np.array([-1, 0, size - 1, size], dtype=np.double) + decpts = incpts[::-1] + + incres = interp(incpts, xp, yp) + decres = interp(decpts, xp, yp) + inctgt = np.array([1, 1, 1, 1], dtype=np.float) + dectgt = inctgt[::-1] + assert_equal(incres, inctgt) + assert_equal(decres, dectgt) + + incres = interp(incpts, xp, yp, left=0) + decres = interp(decpts, xp, yp, left=0) + inctgt = np.array([0, 1, 1, 1], dtype=np.float) + dectgt = inctgt[::-1] + assert_equal(incres, inctgt) + assert_equal(decres, dectgt) + + incres = interp(incpts, xp, yp, right=2) + decres = interp(decpts, xp, yp, right=2) + inctgt = np.array([1, 1, 1, 2], dtype=np.float) + dectgt = inctgt[::-1] + assert_equal(incres, inctgt) + assert_equal(decres, dectgt) + + incres = interp(incpts, xp, yp, left=0, right=2) + decres = interp(decpts, xp, yp, left=0, right=2) + inctgt = np.array([0, 1, 1, 2], dtype=np.float) + dectgt = inctgt[::-1] + assert_equal(incres, inctgt) + assert_equal(decres, dectgt) def test_scalar_interpolation_point(self): x = np.linspace(0, 1, 5) @@ -1674,6 +2491,28 @@ class TestInterp(TestCase): x0 = np.nan assert_almost_equal(np.interp(x0, x, y), x0) + def test_complex_interp(self): + # test complex interpolation + x = np.linspace(0, 1, 5) + y = np.linspace(0, 1, 5) + (1 + np.linspace(0, 1, 5))*1.0j + x0 = 0.3 + y0 = x0 + (1+x0)*1.0j + assert_almost_equal(np.interp(x0, x, y), y0) + # test complex left and right + x0 = -1 + left = 2 + 3.0j + assert_almost_equal(np.interp(x0, x, y, left=left), left) + x0 = 2.0 + right = 2 + 3.0j + assert_almost_equal(np.interp(x0, x, y, right=right), right) + # test complex periodic + x = [-180, -170, -185, 185, -10, -5, 0, 365] + xp = [190, -190, 350, -350] + fp = [5+1.0j, 10+2j, 3+3j, 4+4j] + y = [7.5+1.5j, 5.+1.0j, 8.75+1.75j, 6.25+1.25j, 3.+3j, 3.25+3.25j, + 3.5+3.5j, 3.75+3.75j] + assert_almost_equal(np.interp(x, xp, fp, period=360), y) + def test_zero_dimensional_interpolation_point(self): x = np.linspace(0, 1, 5) y = np.linspace(0, 1, 5) @@ -1703,13 +2542,19 @@ def compare_results(res, desired): assert_array_equal(res[i], desired[i]) -class TestScoreatpercentile(TestCase): +class TestPercentile(TestCase): def test_basic(self): x = np.arange(8) * 0.5 assert_equal(np.percentile(x, 0), 0.) assert_equal(np.percentile(x, 100), 3.5) assert_equal(np.percentile(x, 50), 1.75) + x[1] = np.nan + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', RuntimeWarning) + assert_equal(np.percentile(x, 0), np.nan) + assert_equal(np.percentile(x, 0, interpolation='nearest'), np.nan) + assert_(w[0].category is RuntimeWarning) def test_api(self): d = np.ones(5) @@ -1720,10 +2565,10 @@ class TestScoreatpercentile(TestCase): def test_2D(self): x = np.array([[1, 1, 1], - [1, 1, 1], - [4, 4, 3], - [1, 1, 1], - [1, 1, 1]]) + [1, 1, 1], + [4, 4, 3], + [1, 1, 1], + [1, 1, 1]]) assert_array_equal(np.percentile(x, 50, axis=0), [1, 1, 1]) def test_linear(self): @@ -1731,7 +2576,7 @@ class TestScoreatpercentile(TestCase): # Test defaults assert_equal(np.percentile(range(10), 50), 4.5) - # explicitly specify interpolation_method 'fraction' (the default) + # explicitly specify interpolation_method 'linear' (the default) assert_equal(np.percentile(range(10), 50, interpolation='linear'), 4.5) @@ -1746,6 +2591,10 @@ class TestScoreatpercentile(TestCase): def test_midpoint(self): assert_equal(np.percentile(range(10), 51, interpolation='midpoint'), 4.5) + assert_equal(np.percentile(range(11), 51, + interpolation='midpoint'), 5.5) + assert_equal(np.percentile(range(11), 50, + interpolation='midpoint'), 5) def test_nearest(self): assert_equal(np.percentile(range(10), 51, @@ -1776,7 +2625,8 @@ class TestScoreatpercentile(TestCase): assert_equal(np.percentile(x, (25, 50), axis=1).shape, (2, 3, 5, 6)) assert_equal(np.percentile(x, (25, 50), axis=2).shape, (2, 3, 4, 6)) assert_equal(np.percentile(x, (25, 50), axis=3).shape, (2, 3, 4, 5)) - assert_equal(np.percentile(x, (25, 50, 75), axis=1).shape, (3, 3, 5, 6)) + assert_equal( + np.percentile(x, (25, 50, 75), axis=1).shape, (3, 3, 5, 6)) assert_equal(np.percentile(x, (25, 50), interpolation="higher").shape, (2,)) assert_equal(np.percentile(x, (25, 50, 75), @@ -1797,10 +2647,10 @@ class TestScoreatpercentile(TestCase): x = np.arange(12).reshape(3, 4) assert_equal(np.percentile(x, 50), 5.5) self.assertTrue(np.isscalar(np.percentile(x, 50))) - r0 = np.array([ 4., 5., 6., 7.]) + r0 = np.array([4., 5., 6., 7.]) assert_equal(np.percentile(x, 50, axis=0), r0) assert_equal(np.percentile(x, 50, axis=0).shape, r0.shape) - r1 = np.array([ 1.5, 5.5, 9.5]) + r1 = np.array([1.5, 5.5, 9.5]) assert_almost_equal(np.percentile(x, 50, axis=1), r1) assert_equal(np.percentile(x, 50, axis=1).shape, r1.shape) @@ -1818,11 +2668,11 @@ class TestScoreatpercentile(TestCase): x = np.arange(12).reshape(3, 4) assert_equal(np.percentile(x, 50, interpolation='lower'), 5.) self.assertTrue(np.isscalar(np.percentile(x, 50))) - r0 = np.array([ 4., 5., 6., 7.]) + r0 = np.array([4., 5., 6., 7.]) c0 = np.percentile(x, 50, interpolation='lower', axis=0) assert_equal(c0, r0) assert_equal(c0.shape, r0.shape) - r1 = np.array([ 1., 5., 9.]) + r1 = np.array([1., 5., 9.]) c1 = np.percentile(x, 50, interpolation='lower', axis=1) assert_almost_equal(c1, r1) assert_equal(c1.shape, r1.shape) @@ -1894,7 +2744,7 @@ class TestScoreatpercentile(TestCase): def test_percentile_empty_dim(self): # empty dims are preserved - d = np.arange(11*2).reshape(11, 1, 2, 1) + d = np.arange(11 * 2).reshape(11, 1, 2, 1) assert_array_equal(np.percentile(d, 50, axis=0).shape, (1, 2, 1)) assert_array_equal(np.percentile(d, 50, axis=1).shape, (11, 2, 1)) assert_array_equal(np.percentile(d, 50, axis=2).shape, (11, 1, 1)) @@ -1920,7 +2770,6 @@ class TestScoreatpercentile(TestCase): assert_array_equal(np.array(np.percentile(d, [10, 50], axis=3)).shape, (2, 11, 1, 2)) - def test_percentile_no_overwrite(self): a = np.array([2, 3, 4, 1]) np.percentile(a, [50], overwrite_input=False) @@ -1961,22 +2810,22 @@ class TestScoreatpercentile(TestCase): assert_equal(np.percentile(x, [25, 60], axis=(0,)), np.percentile(x, [25, 60], axis=0)) - d = np.arange(3 * 5 * 7 * 11).reshape(3, 5, 7, 11) - np.random.shuffle(d) + d = np.arange(3 * 5 * 7 * 11).reshape((3, 5, 7, 11)) + np.random.shuffle(d.ravel()) assert_equal(np.percentile(d, 25, axis=(0, 1, 2))[0], - np.percentile(d[:, :, :, 0].flatten(), 25)) + np.percentile(d[:,:,:, 0].flatten(), 25)) assert_equal(np.percentile(d, [10, 90], axis=(0, 1, 3))[:, 1], - np.percentile(d[:, :, 1, :].flatten(), [10, 90])) + np.percentile(d[:,:, 1,:].flatten(), [10, 90])) assert_equal(np.percentile(d, 25, axis=(3, 1, -4))[2], - np.percentile(d[:, :, 2, :].flatten(), 25)) + np.percentile(d[:,:, 2,:].flatten(), 25)) assert_equal(np.percentile(d, 25, axis=(3, 1, 2))[2], - np.percentile(d[2, :, :, :].flatten(), 25)) + np.percentile(d[2,:,:,:].flatten(), 25)) assert_equal(np.percentile(d, 25, axis=(3, 2))[2, 1], - np.percentile(d[2, 1, :, :].flatten(), 25)) + np.percentile(d[2, 1,:,:].flatten(), 25)) assert_equal(np.percentile(d, 25, axis=(1, -2))[2, 1], - np.percentile(d[2, :, :, 1].flatten(), 25)) + np.percentile(d[2,:,:, 1].flatten(), 25)) assert_equal(np.percentile(d, 25, axis=(1, 3))[2, 2], - np.percentile(d[2, :, 2, :].flatten(), 25)) + np.percentile(d[2,:, 2,:].flatten(), 25)) def test_extended_axis_invalid(self): d = np.ones((3, 5, 7, 11)) @@ -2006,8 +2855,123 @@ class TestScoreatpercentile(TestCase): assert_equal(np.percentile(d, [1, 7], axis=(0, 3), keepdims=True).shape, (2, 1, 5, 7, 1)) + def test_out(self): + o = np.zeros((4,)) + d = np.ones((3, 4)) + assert_equal(np.percentile(d, 0, 0, out=o), o) + assert_equal(np.percentile(d, 0, 0, interpolation='nearest', out=o), o) + o = np.zeros((3,)) + assert_equal(np.percentile(d, 1, 1, out=o), o) + assert_equal(np.percentile(d, 1, 1, interpolation='nearest', out=o), o) + + o = np.zeros(()) + assert_equal(np.percentile(d, 2, out=o), o) + assert_equal(np.percentile(d, 2, interpolation='nearest', out=o), o) + + def test_out_nan(self): + with warnings.catch_warnings(record=True): + warnings.filterwarnings('always', '', RuntimeWarning) + o = np.zeros((4,)) + d = np.ones((3, 4)) + d[2, 1] = np.nan + assert_equal(np.percentile(d, 0, 0, out=o), o) + assert_equal( + np.percentile(d, 0, 0, interpolation='nearest', out=o), o) + o = np.zeros((3,)) + assert_equal(np.percentile(d, 1, 1, out=o), o) + assert_equal( + np.percentile(d, 1, 1, interpolation='nearest', out=o), o) + o = np.zeros(()) + assert_equal(np.percentile(d, 1, out=o), o) + assert_equal( + np.percentile(d, 1, interpolation='nearest', out=o), o) + + def test_nan_behavior(self): + a = np.arange(24, dtype=float) + a[2] = np.nan + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', RuntimeWarning) + assert_equal(np.percentile(a, 0.3), np.nan) + assert_equal(np.percentile(a, 0.3, axis=0), np.nan) + assert_equal(np.percentile(a, [0.3, 0.6], axis=0), + np.array([np.nan] * 2)) + assert_(w[0].category is RuntimeWarning) + assert_(w[1].category is RuntimeWarning) + assert_(w[2].category is RuntimeWarning) + + a = np.arange(24, dtype=float).reshape(2, 3, 4) + a[1, 2, 3] = np.nan + a[1, 1, 2] = np.nan + + # no axis + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', RuntimeWarning) + assert_equal(np.percentile(a, 0.3), np.nan) + assert_equal(np.percentile(a, 0.3).ndim, 0) + assert_(w[0].category is RuntimeWarning) + + # axis0 zerod + b = np.percentile(np.arange(24, dtype=float).reshape(2, 3, 4), 0.3, 0) + b[2, 3] = np.nan + b[1, 2] = np.nan + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', RuntimeWarning) + assert_equal(np.percentile(a, 0.3, 0), b) + + # axis0 not zerod + b = np.percentile(np.arange(24, dtype=float).reshape(2, 3, 4), + [0.3, 0.6], 0) + b[:, 2, 3] = np.nan + b[:, 1, 2] = np.nan + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', RuntimeWarning) + assert_equal(np.percentile(a, [0.3, 0.6], 0), b) + + # axis1 zerod + b = np.percentile(np.arange(24, dtype=float).reshape(2, 3, 4), 0.3, 1) + b[1, 3] = np.nan + b[1, 2] = np.nan + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', RuntimeWarning) + assert_equal(np.percentile(a, 0.3, 1), b) + # axis1 not zerod + b = np.percentile( + np.arange(24, dtype=float).reshape(2, 3, 4), [0.3, 0.6], 1) + b[:, 1, 3] = np.nan + b[:, 1, 2] = np.nan + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', RuntimeWarning) + assert_equal(np.percentile(a, [0.3, 0.6], 1), b) + + # axis02 zerod + b = np.percentile( + np.arange(24, dtype=float).reshape(2, 3, 4), 0.3, (0, 2)) + b[1] = np.nan + b[2] = np.nan + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', RuntimeWarning) + assert_equal(np.percentile(a, 0.3, (0, 2)), b) + # axis02 not zerod + b = np.percentile(np.arange(24, dtype=float).reshape(2, 3, 4), + [0.3, 0.6], (0, 2)) + b[:, 1] = np.nan + b[:, 2] = np.nan + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', RuntimeWarning) + assert_equal(np.percentile(a, [0.3, 0.6], (0, 2)), b) + # axis02 not zerod with nearest interpolation + b = np.percentile(np.arange(24, dtype=float).reshape(2, 3, 4), + [0.3, 0.6], (0, 2), interpolation='nearest') + b[:, 1] = np.nan + b[:, 2] = np.nan + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', RuntimeWarning) + assert_equal(np.percentile( + a, [0.3, 0.6], (0, 2), interpolation='nearest'), b) + class TestMedian(TestCase): + def test_basic(self): a0 = np.array(1) a1 = np.arange(2) @@ -2028,7 +2992,10 @@ class TestMedian(TestCase): # check array scalar result assert_equal(np.median(a).ndim, 0) a[1] = np.nan - assert_equal(np.median(a).ndim, 0) + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', RuntimeWarning) + assert_equal(np.median(a).ndim, 0) + assert_(w[0].category is RuntimeWarning) def test_axis_keyword(self): a3 = np.array([[2, 3], @@ -2071,7 +3038,7 @@ class TestMedian(TestCase): [3, 4]) a4 = np.arange(3 * 4 * 5, dtype=np.float32).reshape((3, 4, 5)) - map(np.random.shuffle, a4) + np.random.shuffle(a4.ravel()) assert_allclose(np.median(a4, axis=None), np.median(a4.copy(), axis=None, overwrite_input=True)) assert_allclose(np.median(a4, axis=0), @@ -2091,6 +3058,7 @@ class TestMedian(TestCase): def test_subclass(self): # gh-3846 class MySubClass(np.ndarray): + def __new__(cls, input_array, info=None): obj = np.asarray(input_array).view(cls) obj.info = info @@ -2099,11 +3067,108 @@ class TestMedian(TestCase): def mean(self, axis=None, dtype=None, out=None): return -7 - a = MySubClass([1,2,3]) + a = MySubClass([1, 2, 3]) assert_equal(np.median(a), -7) + def test_out(self): + o = np.zeros((4,)) + d = np.ones((3, 4)) + assert_equal(np.median(d, 0, out=o), o) + o = np.zeros((3,)) + assert_equal(np.median(d, 1, out=o), o) + o = np.zeros(()) + assert_equal(np.median(d, out=o), o) + + def test_out_nan(self): + with warnings.catch_warnings(record=True): + warnings.filterwarnings('always', '', RuntimeWarning) + o = np.zeros((4,)) + d = np.ones((3, 4)) + d[2, 1] = np.nan + assert_equal(np.median(d, 0, out=o), o) + o = np.zeros((3,)) + assert_equal(np.median(d, 1, out=o), o) + o = np.zeros(()) + assert_equal(np.median(d, out=o), o) + + def test_nan_behavior(self): + a = np.arange(24, dtype=float) + a[2] = np.nan + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', RuntimeWarning) + assert_equal(np.median(a), np.nan) + assert_equal(np.median(a, axis=0), np.nan) + assert_(w[0].category is RuntimeWarning) + assert_(w[1].category is RuntimeWarning) + + a = np.arange(24, dtype=float).reshape(2, 3, 4) + a[1, 2, 3] = np.nan + a[1, 1, 2] = np.nan + + # no axis + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', RuntimeWarning) + assert_equal(np.median(a), np.nan) + assert_equal(np.median(a).ndim, 0) + assert_(w[0].category is RuntimeWarning) + + # axis0 + b = np.median(np.arange(24, dtype=float).reshape(2, 3, 4), 0) + b[2, 3] = np.nan + b[1, 2] = np.nan + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', RuntimeWarning) + assert_equal(np.median(a, 0), b) + assert_equal(len(w), 1) + + # axis1 + b = np.median(np.arange(24, dtype=float).reshape(2, 3, 4), 1) + b[1, 3] = np.nan + b[1, 2] = np.nan + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', RuntimeWarning) + assert_equal(np.median(a, 1), b) + assert_equal(len(w), 1) + + # axis02 + b = np.median(np.arange(24, dtype=float).reshape(2, 3, 4), (0, 2)) + b[1] = np.nan + b[2] = np.nan + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', RuntimeWarning) + assert_equal(np.median(a, (0, 2)), b) + assert_equal(len(w), 1) + + def test_empty(self): + # empty arrays + a = np.array([], dtype=float) + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', RuntimeWarning) + assert_equal(np.median(a), np.nan) + assert_(w[0].category is RuntimeWarning) + + # multiple dimensions + a = np.array([], dtype=float, ndmin=3) + # no axis + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', RuntimeWarning) + assert_equal(np.median(a), np.nan) + assert_(w[0].category is RuntimeWarning) + + # axis 0 and 1 + b = np.array([], dtype=float, ndmin=2) + assert_equal(np.median(a, axis=0), b) + assert_equal(np.median(a, axis=1), b) + + # axis 2 + b = np.array(np.nan, dtype=float, ndmin=2) + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', RuntimeWarning) + assert_equal(np.median(a, axis=2), b) + assert_(w[0].category is RuntimeWarning) + def test_object(self): - o = np.arange(7.); + o = np.arange(7.) assert_(type(np.median(o.astype(object))), float) o[2] = np.nan assert_(type(np.median(o.astype(object))), float) @@ -2121,22 +3186,22 @@ class TestMedian(TestCase): assert_equal(np.median(x, axis=(0, )), np.median(x, axis=0)) assert_equal(np.median(x, axis=(-1, )), np.median(x, axis=-1)) - d = np.arange(3 * 5 * 7 * 11).reshape(3, 5, 7, 11) - np.random.shuffle(d) + d = np.arange(3 * 5 * 7 * 11).reshape((3, 5, 7, 11)) + np.random.shuffle(d.ravel()) assert_equal(np.median(d, axis=(0, 1, 2))[0], - np.median(d[:, :, :, 0].flatten())) + np.median(d[:,:,:, 0].flatten())) assert_equal(np.median(d, axis=(0, 1, 3))[1], - np.median(d[:, :, 1, :].flatten())) + np.median(d[:,:, 1,:].flatten())) assert_equal(np.median(d, axis=(3, 1, -4))[2], - np.median(d[:, :, 2, :].flatten())) + np.median(d[:,:, 2,:].flatten())) assert_equal(np.median(d, axis=(3, 1, 2))[2], - np.median(d[2, :, :, :].flatten())) + np.median(d[2,:,:,:].flatten())) assert_equal(np.median(d, axis=(3, 2))[2, 1], - np.median(d[2, 1, :, :].flatten())) + np.median(d[2, 1,:,:].flatten())) assert_equal(np.median(d, axis=(1, -2))[2, 1], - np.median(d[2, :, :, 1].flatten())) + np.median(d[2,:,:, 1].flatten())) assert_equal(np.median(d, axis=(1, 3))[2, 2], - np.median(d[2, :, 2, :].flatten())) + np.median(d[2,:, 2,:].flatten())) def test_extended_axis_invalid(self): d = np.ones((3, 5, 7, 11)) @@ -2162,7 +3227,6 @@ class TestMedian(TestCase): (1, 1, 7, 1)) - class TestAdd_newdoc_ufunc(TestCase): def test_ufunc_arg(self): diff --git a/numpy/lib/tests/test_index_tricks.py b/numpy/lib/tests/test_index_tricks.py index 97047c53a..d9fa1f43e 100644 --- a/numpy/lib/tests/test_index_tricks.py +++ b/numpy/lib/tests/test_index_tricks.py @@ -7,7 +7,7 @@ from numpy.testing import ( ) from numpy.lib.index_tricks import ( mgrid, ndenumerate, fill_diagonal, diag_indices, diag_indices_from, - index_exp, ndindex, r_, s_ + index_exp, ndindex, r_, s_, ix_ ) @@ -47,6 +47,27 @@ class TestRavelUnravelIndex(TestCase): [[3, 6, 6], [4, 5, 1]]) assert_equal(np.unravel_index(1621, (6, 7, 8, 9)), [3, 1, 4, 1]) + def test_big_indices(self): + # ravel_multi_index for big indices (issue #7546) + if np.intp == np.int64: + arr = ([1, 29], [3, 5], [3, 117], [19, 2], + [2379, 1284], [2, 2], [0, 1]) + assert_equal( + np.ravel_multi_index(arr, (41, 7, 120, 36, 2706, 8, 6)), + [5627771580, 117259570957]) + + # test overflow checking for too big array (issue #7546) + dummy_arr = ([0],[0]) + half_max = np.iinfo(np.intp).max // 2 + assert_equal( + np.ravel_multi_index(dummy_arr, (half_max, 2)), [0]) + assert_raises(ValueError, + np.ravel_multi_index, dummy_arr, (half_max+1, 2)) + assert_equal( + np.ravel_multi_index(dummy_arr, (half_max, 2), order='F'), [0]) + assert_raises(ValueError, + np.ravel_multi_index, dummy_arr, (half_max+1, 2), order='F') + def test_dtypes(self): # Test with different data types for dtype in [np.int16, np.uint16, np.int32, @@ -86,6 +107,12 @@ class TestRavelUnravelIndex(TestCase): assert_raises( ValueError, np.ravel_multi_index, [5, 1, -1, 2], (4, 3, 7, 12)) + def test_writeability(self): + # See gh-7269 + x, y = np.unravel_index([1, 2, 3], (4, 5)) + self.assertTrue(x.flags.writeable) + self.assertTrue(y.flags.writeable) + class TestGrid(TestCase): def test_basic(self): @@ -169,6 +196,43 @@ class TestIndexExpression(TestCase): assert_equal(a[:, :3, [1, 2]], a[s_[:, :3, [1, 2]]]) +class TestIx_(TestCase): + def test_regression_1(self): + # Test empty inputs create ouputs of indexing type, gh-5804 + # Test both lists and arrays + for func in (range, np.arange): + a, = np.ix_(func(0)) + assert_equal(a.dtype, np.intp) + + def test_shape_and_dtype(self): + sizes = (4, 5, 3, 2) + # Test both lists and arrays + for func in (range, np.arange): + arrays = np.ix_(*[func(sz) for sz in sizes]) + for k, (a, sz) in enumerate(zip(arrays, sizes)): + assert_equal(a.shape[k], sz) + assert_(all(sh == 1 for j, sh in enumerate(a.shape) if j != k)) + assert_(np.issubdtype(a.dtype, int)) + + def test_bool(self): + bool_a = [True, False, True, True] + int_a, = np.nonzero(bool_a) + assert_equal(np.ix_(bool_a)[0], int_a) + + def test_1d_only(self): + idx2d = [[1, 2, 3], [4, 5, 6]] + assert_raises(ValueError, np.ix_, idx2d) + + def test_repeated_input(self): + length_of_vector = 5 + x = np.arange(length_of_vector) + out = ix_(x, x) + assert_equal(out[0].shape, (length_of_vector, 1)) + assert_equal(out[1].shape, (1, length_of_vector)) + # check that input shape is not modified + assert_equal(x.shape, (length_of_vector,)) + + def test_c_(): a = np.c_[np.array([[1, 2, 3]]), 0, 0, np.array([[4, 5, 6]])] assert_equal(a, [[1, 2, 3, 0, 0, 4, 5, 6]]) diff --git a/numpy/lib/tests/test_io.py b/numpy/lib/tests/test_io.py index 68b2018cd..333891d46 100644 --- a/numpy/lib/tests/test_io.py +++ b/numpy/lib/tests/test_io.py @@ -4,7 +4,7 @@ import sys import gzip import os import threading -from tempfile import mkstemp, NamedTemporaryFile +from tempfile import NamedTemporaryFile import time import warnings import gc @@ -13,16 +13,14 @@ from datetime import datetime import numpy as np import numpy.ma as ma -from numpy.lib._iotools import (ConverterError, ConverterLockError, - ConversionWarning) -from numpy.compat import asbytes, asbytes_nested, bytes, asstr -from nose import SkipTest -from numpy.ma.testutils import ( - TestCase, assert_equal, assert_array_equal, - assert_raises, assert_raises_regex, run_module_suite +from numpy.lib._iotools import ConverterError, ConversionWarning +from numpy.compat import asbytes, bytes, unicode, Path +from numpy.ma.testutils import assert_equal +from numpy.testing import ( + TestCase, run_module_suite, assert_warns, assert_, + assert_raises_regex, assert_raises, assert_allclose, + assert_array_equal, temppath, dec, IS_PYPY, suppress_warnings ) -from numpy.testing import assert_warns, assert_, build_err_msg -from numpy.testing.utils import tempdir class TextIO(BytesIO): @@ -49,8 +47,9 @@ IS_64BIT = sys.maxsize > 2**32 def strptime(s, fmt=None): - """This function is available in the datetime module only - from Python >= 2.5. + """ + This function is available in the datetime module only from Python >= + 2.5. """ if sys.version_info[0] >= 3: @@ -158,6 +157,7 @@ class RoundtripTest(object): a = np.array([(1, 2), (3, 4)], dtype=[('x', 'i4'), ('y', 'i4')]) self.check_roundtrips(a) + @dec.slow def test_format_2_0(self): dt = [(("%d" % i) * 100, float) for i in range(500)] a = np.ones(1000, dtype=dt) @@ -194,13 +194,13 @@ class TestSavezLoad(RoundtripTest, TestCase): def test_big_arrays(self): L = (1 << 31) + 100000 a = np.empty(L, dtype=np.uint8) - with tempdir(prefix="numpy_test_big_arrays_") as tmpdir: - tmp = os.path.join(tmpdir, "file.npz") + with temppath(prefix="numpy_test_big_arrays_", suffix=".npz") as tmp: np.savez(tmp, a=a) del a npfile = np.load(tmp) - a = npfile['a'] + a = npfile['a'] # Should succeed npfile.close() + del a # Avoid pyflakes unused variable warning. def test_multiple_arrays(self): a = np.array([[1, 2], [3, 4]], float) @@ -216,7 +216,7 @@ class TestSavezLoad(RoundtripTest, TestCase): l = np.load(c) assert_equal(a, l['file_a']) assert_equal(b, l['file_b']) - + def test_BagObj(self): a = np.array([[1, 2], [3, 4]], float) b = np.array([[1 + 2j, 2 + 7j], [3 - 6j, 4 + 12j]], complex) @@ -233,16 +233,12 @@ class TestSavezLoad(RoundtripTest, TestCase): # and savez functions in multithreaded environment def writer(error_list): - fd, tmp = mkstemp(suffix='.npz') - os.close(fd) - try: + with temppath(suffix='.npz') as tmp: arr = np.random.randn(500, 500) try: np.savez(tmp, arr=arr) except OSError as err: error_list.append(err) - finally: - os.remove(tmp) errors = [] threads = [threading.Thread(target=writer, args=(errors,)) @@ -258,40 +254,27 @@ class TestSavezLoad(RoundtripTest, TestCase): def test_not_closing_opened_fid(self): # Test that issue #2178 is fixed: # verify could seek on 'loaded' file - - fd, tmp = mkstemp(suffix='.npz') - os.close(fd) - try: - fp = open(tmp, 'wb') - np.savez(fp, data='LOVELY LOAD') - fp.close() - - fp = open(tmp, 'rb', 10000) - fp.seek(0) - assert_(not fp.closed) - _ = np.load(fp)['data'] - assert_(not fp.closed) - # must not get closed by .load(opened fp) - fp.seek(0) - assert_(not fp.closed) - - finally: - fp.close() - os.remove(tmp) - + with temppath(suffix='.npz') as tmp: + with open(tmp, 'wb') as fp: + np.savez(fp, data='LOVELY LOAD') + with open(tmp, 'rb', 10000) as fp: + fp.seek(0) + assert_(not fp.closed) + np.load(fp)['data'] + # fp must not get closed by .load + assert_(not fp.closed) + fp.seek(0) + assert_(not fp.closed) + + @np.testing.dec.skipif(IS_PYPY, "context manager required on PyPy") def test_closing_fid(self): # Test that issue #1517 (too many opened files) remains closed # It might be a "weak" test since failed to get triggered on # e.g. Debian sid of 2012 Jul 05 but was reported to # trigger the failure on Ubuntu 10.04: # http://projects.scipy.org/numpy/ticket/1517#comment:2 - fd, tmp = mkstemp(suffix='.npz') - os.close(fd) - - try: - fp = open(tmp, 'wb') - np.savez(fp, data='LOVELY LOAD') - fp.close() + with temppath(suffix='.npz') as tmp: + np.savez(tmp, data='LOVELY LOAD') # We need to check if the garbage collector can properly close # numpy npz file returned by np.load when their reference count # goes to zero. Python 3 running in debug mode raises a @@ -299,24 +282,22 @@ class TestSavezLoad(RoundtripTest, TestCase): # collector, so we catch the warnings. Because ResourceWarning # is unknown in Python < 3.x, we take the easy way out and # catch all warnings. - with warnings.catch_warnings(): - warnings.simplefilter("ignore") + with suppress_warnings() as sup: + sup.filter(Warning) # TODO: specify exact message for i in range(1, 1025): try: np.load(tmp)["data"] except Exception as e: msg = "Failed to load data from a file: %s" % e raise AssertionError(msg) - finally: - os.remove(tmp) def test_closing_zipfile_after_load(self): - # Check that zipfile owns file and can close it. - # This needs to pass a file name to load for the - # test. - with tempdir(prefix="numpy_test_closing_zipfile_after_load_") as tmpdir: - fd, tmp = mkstemp(suffix='.npz', dir=tmpdir) - os.close(fd) + # Check that zipfile owns file and can close it. This needs to + # pass a file name to load for the test. On windows failure will + # cause a second error will be raised when the attempt to remove + # the open file is made. + prefix = 'numpy_test_closing_zipfile_after_load_' + with temppath(suffix='.npz', prefix=prefix) as tmp: np.savez(tmp, lab='place holder') data = np.load(tmp) fp = data.zip.fp @@ -390,9 +371,8 @@ class TestSaveTxt(TestCase): assert_raises(ValueError, np.savetxt, c, a, fmt=99) def test_header_footer(self): - """ - Test the functionality of the header and footer keyword argument. - """ + # Test the functionality of the header and footer keyword argument. + c = BytesIO() a = np.array([(1, 2), (3, 4)], dtype=np.int) test_header_footer = 'Test header / footer' @@ -425,15 +405,11 @@ class TestSaveTxt(TestCase): asbytes('1 2\n3 4\n' + commentstr + test_header_footer + '\n')) def test_file_roundtrip(self): - f, name = mkstemp() - os.close(f) - try: + with temppath() as name: a = np.array([(1, 2), (3, 4)]) np.savetxt(name, a) b = np.loadtxt(name) assert_array_equal(a, b) - finally: - os.unlink(name) def test_complex_arrays(self): ncols = 2 @@ -553,15 +529,49 @@ class TestLoadTxt(TestCase): a = np.array([[2, -999], [7, 9]], int) assert_array_equal(x, a) - def test_comments(self): + def test_comments_unicode(self): c = TextIO() c.write('# comment\n1,2,3,5\n') c.seek(0) x = np.loadtxt(c, dtype=int, delimiter=',', - comments='#') + comments=unicode('#')) + a = np.array([1, 2, 3, 5], int) + assert_array_equal(x, a) + + def test_comments_byte(self): + c = TextIO() + c.write('# comment\n1,2,3,5\n') + c.seek(0) + x = np.loadtxt(c, dtype=int, delimiter=',', + comments=b'#') + a = np.array([1, 2, 3, 5], int) + assert_array_equal(x, a) + + def test_comments_multiple(self): + c = TextIO() + c.write('# comment\n1,2,3\n@ comment2\n4,5,6 // comment3') + c.seek(0) + x = np.loadtxt(c, dtype=int, delimiter=',', + comments=['#', '@', '//']) + a = np.array([[1, 2, 3], [4, 5, 6]], int) + assert_array_equal(x, a) + + def test_comments_multi_chars(self): + c = TextIO() + c.write('/* comment\n1,2,3,5\n') + c.seek(0) + x = np.loadtxt(c, dtype=int, delimiter=',', + comments='/*') a = np.array([1, 2, 3, 5], int) assert_array_equal(x, a) + # Check that '/*' is not transformed to ['/', '*'] + c = TextIO() + c.write('*/ comment\n1,2,3,5\n') + c.seek(0) + assert_raises(ValueError, np.loadtxt, c, dtype=int, delimiter=',', + comments='/*') + def test_skiprows(self): c = TextIO() c.write('comment\n1,2,3,5\n') @@ -599,6 +609,29 @@ class TestLoadTxt(TestCase): x = np.loadtxt(c, dtype=float, usecols=np.array([1, 2])) assert_array_equal(x, a[:, 1:]) + # Testing with an integer instead of a sequence + for int_type in [int, np.int8, np.int16, + np.int32, np.int64, np.uint8, np.uint16, + np.uint32, np.uint64]: + to_read = int_type(1) + c.seek(0) + x = np.loadtxt(c, dtype=float, usecols=to_read) + assert_array_equal(x, a[:, 1]) + + # Testing with some crazy custom integer type + class CrazyInt(object): + def __index__(self): + return 1 + + crazy_int = CrazyInt() + c.seek(0) + x = np.loadtxt(c, dtype=float, usecols=crazy_int) + assert_array_equal(x, a[:, 1]) + + c.seek(0) + x = np.loadtxt(c, dtype=float, usecols=(crazy_int,)) + assert_array_equal(x, a[:, 1]) + # Checking with dtypes defined converters. data = '''JOE 70.1 25.3 BOB 60.5 27.9 @@ -610,6 +643,21 @@ class TestLoadTxt(TestCase): assert_equal(arr['stid'], [b"JOE", b"BOB"]) assert_equal(arr['temp'], [25.3, 27.9]) + # Testing non-ints in usecols + c.seek(0) + bogus_idx = 1.5 + assert_raises_regex( + TypeError, + '^usecols must be.*%s' % type(bogus_idx), + np.loadtxt, c, usecols=bogus_idx + ) + + assert_raises_regex( + TypeError, + '^usecols must be.*%s' % type(bogus_idx), + np.loadtxt, c, usecols=[0, bogus_idx, 0] + ) + def test_fancy_dtype(self): c = TextIO() c.write('1,2,3.0\n4,5,6.0\n') @@ -639,9 +687,8 @@ class TestLoadTxt(TestCase): assert_array_equal(x, a) def test_empty_file(self): - with warnings.catch_warnings(): - warnings.filterwarnings("ignore", - message="loadtxt: Empty input file:") + with suppress_warnings() as sup: + sup.filter(message="loadtxt: Empty input file:") c = TextIO() x = np.loadtxt(c) assert_equal(x.shape, (0,)) @@ -663,9 +710,7 @@ class TestLoadTxt(TestCase): assert_array_equal(data, [33, 66]) def test_dtype_with_object(self): - "Test using an explicit dtype with an object" - from datetime import date - import time + # Test using an explicit dtype with an object data = """ 1; 2001-01-01 2; 2002-01-31 """ ndtype = [('idx', int), ('code', np.object)] @@ -694,16 +739,33 @@ class TestLoadTxt(TestCase): res = np.loadtxt(c, dtype=np.int64) assert_equal(res, tgt) - def test_universal_newline(self): - f, name = mkstemp() - os.write(f, b'1 21\r3 42\r') - os.close(f) + def test_from_float_hex(self): + # IEEE doubles and floats only, otherwise the float32 + # conversion may fail. + tgt = np.logspace(-10, 10, 5).astype(np.float32) + tgt = np.hstack((tgt, -tgt)).astype(np.float) + inp = '\n'.join(map(float.hex, tgt)) + c = TextIO() + c.write(inp) + for dt in [np.float, np.float32]: + c.seek(0) + res = np.loadtxt(c, dtype=dt) + assert_equal(res, tgt, err_msg="%s" % dt) + + def test_from_complex(self): + tgt = (complex(1, 1), complex(1, -1)) + c = TextIO() + c.write("%s %s" % tgt) + c.seek(0) + res = np.loadtxt(c, dtype=np.complex) + assert_equal(res, tgt) - try: + def test_universal_newline(self): + with temppath() as name: + with open(name, 'w') as f: + f.write('1 21\r3 42\r') data = np.loadtxt(name) - assert_array_equal(data, [[1, 21], [3, 42]]) - finally: - os.unlink(name) + assert_array_equal(data, [[1, 21], [3, 42]]) def test_empty_field_after_tab(self): c = TextIO() @@ -763,9 +825,8 @@ class TestLoadTxt(TestCase): assert_(x.shape == (3,)) # Test ndmin kw with empty file. - with warnings.catch_warnings(): - warnings.filterwarnings("ignore", - message="loadtxt: Empty input file:") + with suppress_warnings() as sup: + sup.filter(message="loadtxt: Empty input file:") f = TextIO() assert_(np.loadtxt(f, ndmin=2).shape == (0, 1,)) assert_(np.loadtxt(f, ndmin=1).shape == (0,)) @@ -786,6 +847,14 @@ class TestLoadTxt(TestCase): # Check for exception and that exception contains line number assert_raises_regex(ValueError, "3", np.loadtxt, c) + def test_none_as_string(self): + # gh-5155, None should work as string when format demands it + c = TextIO() + c.write('100,foo,200\n300,None,400') + c.seek(0) + dt = np.dtype([('x', int), ('a', 'S10'), ('y', int)]) + np.loadtxt(c, delimiter=',', dtype=dt, comments=None) # Should succeed + class Testfromregex(TestCase): # np.fromregex expects files opened in binary mode. @@ -828,15 +897,13 @@ class Testfromregex(TestCase): class TestFromTxt(TestCase): # def test_record(self): - "Test w/ explicit dtype" + # Test w/ explicit dtype data = TextIO('1 2\n3 4') -# data.seek(0) test = np.ndfromtxt(data, dtype=[('x', np.int32), ('y', np.int32)]) control = np.array([(1, 2), (3, 4)], dtype=[('x', 'i4'), ('y', 'i4')]) assert_equal(test, control) # data = TextIO('M 64.0 75.0\nF 25.0 60.0') -# data.seek(0) descriptor = {'names': ('gender', 'age', 'weight'), 'formats': ('S1', 'i4', 'f4')} control = np.array([('M', 64.0, 75.0), ('F', 25.0, 60.0)], @@ -845,7 +912,7 @@ class TestFromTxt(TestCase): assert_equal(test, control) def test_array(self): - "Test outputing a standard ndarray" + # Test outputing a standard ndarray data = TextIO('1 2\n3 4') control = np.array([[1, 2], [3, 4]], dtype=int) test = np.ndfromtxt(data, dtype=int) @@ -857,7 +924,7 @@ class TestFromTxt(TestCase): assert_array_equal(test, control) def test_1D(self): - "Test squeezing to 1D" + # Test squeezing to 1D control = np.array([1, 2, 3, 4], int) # data = TextIO('1\n2\n3\n4\n') @@ -869,7 +936,7 @@ class TestFromTxt(TestCase): assert_array_equal(test, control) def test_comments(self): - "Test the stripping of comments" + # Test the stripping of comments control = np.array([1, 2, 3, 5], int) # Comment on its own line data = TextIO('# comment\n1,2,3,5\n') @@ -881,7 +948,7 @@ class TestFromTxt(TestCase): assert_equal(test, control) def test_skiprows(self): - "Test row skipping" + # Test row skipping control = np.array([1, 2, 3, 5], int) kwargs = dict(dtype=int, delimiter=',') # @@ -905,8 +972,8 @@ class TestFromTxt(TestCase): assert_equal(test, ctrl) def test_skip_footer_with_invalid(self): - with warnings.catch_warnings(): - warnings.filterwarnings("ignore") + with suppress_warnings() as sup: + sup.filter(ConversionWarning) basestr = '1 1\n2 2\n3 3\n4 4\n5 \n6 \n7 \n' # Footer too small to get rid of all invalid values assert_raises(ValueError, np.genfromtxt, @@ -929,7 +996,7 @@ class TestFromTxt(TestCase): assert_equal(a, np.array([[1., 1.], [3., 3.], [4., 4.]])) def test_header(self): - "Test retrieving a header" + # Test retrieving a header data = TextIO('gender age weight\nM 64.0 75.0\nF 25.0 60.0') test = np.ndfromtxt(data, dtype=None, names=True) control = {'gender': np.array([b'M', b'F']), @@ -940,7 +1007,7 @@ class TestFromTxt(TestCase): assert_equal(test['weight'], control['weight']) def test_auto_dtype(self): - "Test the automatic definition of the output dtype" + # Test the automatic definition of the output dtype data = TextIO('A 64 75.0 3+4j True\nBCD 25 60.0 5+6j False') test = np.ndfromtxt(data, dtype=None) control = [np.array([b'A', b'BCD']), @@ -953,14 +1020,14 @@ class TestFromTxt(TestCase): assert_equal(test['f%i' % i], ctrl) def test_auto_dtype_uniform(self): - "Tests whether the output dtype can be uniformized" + # Tests whether the output dtype can be uniformized data = TextIO('1 2 3 4\n5 6 7 8\n') test = np.ndfromtxt(data, dtype=None) control = np.array([[1, 2, 3, 4], [5, 6, 7, 8]]) assert_equal(test, control) def test_fancy_dtype(self): - "Check that a nested dtype isn't MIA" + # Check that a nested dtype isn't MIA data = TextIO('1,2,3.0\n4,5,6.0\n') fancydtype = np.dtype([('x', int), ('y', [('t', int), ('s', float)])]) test = np.ndfromtxt(data, dtype=fancydtype, delimiter=',') @@ -968,7 +1035,7 @@ class TestFromTxt(TestCase): assert_equal(test, control) def test_names_overwrite(self): - "Test overwriting the names of the dtype" + # Test overwriting the names of the dtype descriptor = {'names': ('g', 'a', 'w'), 'formats': ('S1', 'i4', 'f4')} data = TextIO(b'M 64.0 75.0\nF 25.0 60.0') @@ -980,7 +1047,7 @@ class TestFromTxt(TestCase): assert_equal(test, control) def test_commented_header(self): - "Check that names can be retrieved even if the line is commented out." + # Check that names can be retrieved even if the line is commented out. data = TextIO(""" #gender age weight M 21 72.100000 @@ -1003,7 +1070,7 @@ M 33 21.99 assert_equal(test, ctrl) def test_autonames_and_usecols(self): - "Tests names and usecols" + # Tests names and usecols data = TextIO('A B C D\n aaaa 121 45 9.1') test = np.ndfromtxt(data, usecols=('A', 'C', 'D'), names=True, dtype=None) @@ -1012,7 +1079,7 @@ M 33 21.99 assert_equal(test, control) def test_converters_with_usecols(self): - "Test the combination user-defined converters and usecol" + # Test the combination user-defined converters and usecol data = TextIO('1,2,3,,5\n6,7,8,9,10\n') test = np.ndfromtxt(data, dtype=int, delimiter=',', converters={3: lambda s: int(s or - 999)}, @@ -1021,7 +1088,7 @@ M 33 21.99 assert_equal(test, control) def test_converters_with_usecols_and_names(self): - "Tests names and usecols" + # Tests names and usecols data = TextIO('A B C D\n aaaa 121 45 9.1') test = np.ndfromtxt(data, usecols=('A', 'C', 'D'), names=True, dtype=None, converters={'C': lambda s: 2 * int(s)}) @@ -1030,7 +1097,7 @@ M 33 21.99 assert_equal(test, control) def test_converters_cornercases(self): - "Test the conversion to datetime." + # Test the conversion to datetime. converter = { 'date': lambda s: strptime(s, '%Y-%m-%d %H:%M:%SZ')} data = TextIO('2009-02-03 12:00:00Z, 72214.0') @@ -1041,7 +1108,7 @@ M 33 21.99 assert_equal(test, control) def test_converters_cornercases2(self): - "Test the conversion to datetime64." + # Test the conversion to datetime64. converter = { 'date': lambda s: np.datetime64(strptime(s, '%Y-%m-%d %H:%M:%SZ'))} data = TextIO('2009-02-03 12:00:00Z, 72214.0') @@ -1052,7 +1119,7 @@ M 33 21.99 assert_equal(test, control) def test_unused_converter(self): - "Test whether unused converters are forgotten" + # Test whether unused converters are forgotten data = TextIO("1 21\n 3 42\n") test = np.ndfromtxt(data, usecols=(1,), converters={0: lambda s: int(s, 16)}) @@ -1077,7 +1144,7 @@ M 33 21.99 assert_raises(ConverterError, np.genfromtxt, s, **kwargs) def test_tricky_converter_bug1666(self): - "Test some corner case" + # Test some corner cases s = TextIO('q1,2\nq3,4') cnv = lambda s: float(s[1:]) test = np.genfromtxt(s, delimiter=',', converters={0: cnv}) @@ -1099,22 +1166,20 @@ M 33 21.99 def test_dtype_with_converters_and_usecols(self): dstr = "1,5,-1,1:1\n2,8,-1,1:n\n3,3,-2,m:n\n" dmap = {'1:1':0, '1:n':1, 'm:1':2, 'm:n':3} - dtyp = [('E1','i4'),('E2','i4'),('E3','i2'),('N', 'i1')] + dtyp = [('e1','i4'),('e2','i4'),('e3','i2'),('n', 'i1')] conv = {0: int, 1: int, 2: int, 3: lambda r: dmap[r.decode()]} test = np.recfromcsv(TextIO(dstr,), dtype=dtyp, delimiter=',', names=None, converters=conv) control = np.rec.array([[1,5,-1,0], [2,8,-1,1], [3,3,-2,3]], dtype=dtyp) assert_equal(test, control) - dtyp = [('E1','i4'),('E2','i4'),('N', 'i1')] + dtyp = [('e1','i4'),('e2','i4'),('n', 'i1')] test = np.recfromcsv(TextIO(dstr,), dtype=dtyp, delimiter=',', usecols=(0,1,3), names=None, converters=conv) control = np.rec.array([[1,5,0], [2,8,1], [3,3,3]], dtype=dtyp) assert_equal(test, control) def test_dtype_with_object(self): - "Test using an explicit dtype with an object" - from datetime import date - import time + # Test using an explicit dtype with an object data = """ 1; 2001-01-01 2; 2002-01-31 """ ndtype = [('idx', int), ('code', np.object)] @@ -1126,7 +1191,7 @@ M 33 21.99 [(1, datetime(2001, 1, 1)), (2, datetime(2002, 1, 31))], dtype=ndtype) assert_equal(test, control) - # + ndtype = [('nest', [('idx', int), ('code', np.object)])] try: test = np.genfromtxt(TextIO(data), delimiter=";", @@ -1138,7 +1203,7 @@ M 33 21.99 raise AssertionError(errmsg) def test_userconverters_with_explicit_dtype(self): - "Test user_converters w/ explicit (standard) dtype" + # Test user_converters w/ explicit (standard) dtype data = TextIO('skip,skip,2001-01-01,1.0,skip') test = np.genfromtxt(data, delimiter=",", names=None, dtype=float, usecols=(2, 3), converters={2: bytes}) @@ -1147,7 +1212,7 @@ M 33 21.99 assert_equal(test, control) def test_spacedelimiter(self): - "Test space delimiter" + # Test space delimiter data = TextIO("1 2 3 4 5\n6 7 8 9 10") test = np.ndfromtxt(data) control = np.array([[1., 2., 3., 4., 5.], @@ -1155,7 +1220,7 @@ M 33 21.99 assert_equal(test, control) def test_integer_delimiter(self): - "Test using an integer for delimiter" + # Test using an integer for delimiter data = " 1 2 3\n 4 5 67\n890123 4" test = np.genfromtxt(TextIO(data), delimiter=3) control = np.array([[1, 2, 3], [4, 5, 67], [890, 123, 4]]) @@ -1169,7 +1234,7 @@ M 33 21.99 assert_equal(test, control) def test_missing_with_tabs(self): - "Test w/ a delimiter tab" + # Test w/ a delimiter tab txt = "1\t2\t3\n\t2\t\n1\t\t3" test = np.genfromtxt(TextIO(txt), delimiter="\t", usemask=True,) @@ -1179,7 +1244,7 @@ M 33 21.99 assert_equal(test.mask, ctrl_m) def test_usecols(self): - "Test the selection of columns" + # Test the selection of columns # Select 1 column control = np.array([[1, 2], [3, 4]], float) data = TextIO() @@ -1200,7 +1265,7 @@ M 33 21.99 assert_equal(test, control[:, 1:]) def test_usecols_as_css(self): - "Test giving usecols with a comma-separated string" + # Test giving usecols with a comma-separated string data = "1 2 3\n4 5 6" test = np.genfromtxt(TextIO(data), names="a, b, c", usecols="a, c") @@ -1208,7 +1273,7 @@ M 33 21.99 assert_equal(test, ctrl) def test_usecols_with_structured_dtype(self): - "Test usecols with an explicit structured dtype" + # Test usecols with an explicit structured dtype data = TextIO("JOE 70.1 25.3\nBOB 60.5 27.9") names = ['stid', 'temp'] dtypes = ['S4', 'f8'] @@ -1218,12 +1283,12 @@ M 33 21.99 assert_equal(test['temp'], [25.3, 27.9]) def test_usecols_with_integer(self): - "Test usecols with an integer" + # Test usecols with an integer test = np.genfromtxt(TextIO(b"1 2 3\n4 5 6"), usecols=0) assert_equal(test, np.array([1., 4.])) def test_usecols_with_named_columns(self): - "Test usecols with named columns" + # Test usecols with named columns ctrl = np.array([(1, 3), (4, 6)], dtype=[('a', float), ('c', float)]) data = "1 2 3\n4 5 6" kwargs = dict(names="a, b, c") @@ -1234,16 +1299,15 @@ M 33 21.99 assert_equal(test, ctrl) def test_empty_file(self): - "Test that an empty file raises the proper warning." - with warnings.catch_warnings(): - warnings.filterwarnings("ignore", - message="genfromtxt: Empty input file:") + # Test that an empty file raises the proper warning. + with suppress_warnings() as sup: + sup.filter(message="genfromtxt: Empty input file:") data = TextIO() test = np.genfromtxt(data) assert_equal(test, np.array([])) def test_fancy_dtype_alt(self): - "Check that a nested dtype isn't MIA" + # Check that a nested dtype isn't MIA data = TextIO('1,2,3.0\n4,5,6.0\n') fancydtype = np.dtype([('x', int), ('y', [('t', int), ('s', float)])]) test = np.mafromtxt(data, dtype=fancydtype, delimiter=',') @@ -1309,7 +1373,7 @@ M 33 21.99 assert_equal(test, control) def test_user_filling_values(self): - "Test with missing and filling values" + # Test with missing and filling values ctrl = np.array([(0, 3), (4, -999)], dtype=[('a', int), ('b', int)]) data = "N/A, 2, 3\n4, ,???" kwargs = dict(delimiter=",", @@ -1347,7 +1411,7 @@ M 33 21.99 assert_equal(test.mask, control.mask) def test_with_masked_column_uniform(self): - "Test masked column" + # Test masked column data = TextIO('1 2 3\n4 5 6\n') test = np.genfromtxt(data, dtype=None, missing_values='2,5', usemask=True) @@ -1355,7 +1419,7 @@ M 33 21.99 assert_equal(test, control) def test_with_masked_column_various(self): - "Test masked column" + # Test masked column data = TextIO('True 2 3\nFalse 5 6\n') test = np.genfromtxt(data, dtype=None, missing_values='2,5', usemask=True) @@ -1365,7 +1429,7 @@ M 33 21.99 assert_equal(test, control) def test_invalid_raise(self): - "Test invalid raise" + # Test invalid raise data = ["1, 1, 1, 1, 1"] * 50 for i in range(5): data[10 * i] = "2, 2, 2, 2 2" @@ -1373,8 +1437,8 @@ M 33 21.99 mdata = TextIO("\n".join(data)) # kwargs = dict(delimiter=",", dtype=None, names=True) - # XXX: is there a better way to get the return value of the callable in - # assert_warns ? + # XXX: is there a better way to get the return value of the + # callable in assert_warns ? ret = {} def f(_ret={}): @@ -1389,7 +1453,7 @@ M 33 21.99 delimiter=",", names=True) def test_invalid_raise_with_usecols(self): - "Test invalid_raise with usecols" + # Test invalid_raise with usecols data = ["1, 1, 1, 1, 1"] * 50 for i in range(5): data[10 * i] = "2, 2, 2, 2 2" @@ -1397,8 +1461,8 @@ M 33 21.99 mdata = TextIO("\n".join(data)) kwargs = dict(delimiter=",", dtype=None, names=True, invalid_raise=False) - # XXX: is there a better way to get the return value of the callable in - # assert_warns ? + # XXX: is there a better way to get the return value of the + # callable in assert_warns ? ret = {} def f(_ret={}): @@ -1416,7 +1480,7 @@ M 33 21.99 assert_equal(mtest, control) def test_inconsistent_dtype(self): - "Test inconsistent dtype" + # Test inconsistent dtype data = ["1, 1, 1, 1, -1.1"] * 50 mdata = TextIO("\n".join(data)) @@ -1426,7 +1490,7 @@ M 33 21.99 assert_raises(ValueError, np.genfromtxt, mdata, **kwargs) def test_default_field_format(self): - "Test default format" + # Test default format data = "0, 1, 2.3\n4, 5, 6.7" mtest = np.ndfromtxt(TextIO(data), delimiter=",", dtype=None, defaultfmt="f%02i") @@ -1435,7 +1499,7 @@ M 33 21.99 assert_equal(mtest, ctrl) def test_single_dtype_wo_names(self): - "Test single dtype w/o names" + # Test single dtype w/o names data = "0, 1, 2.3\n4, 5, 6.7" mtest = np.ndfromtxt(TextIO(data), delimiter=",", dtype=float, defaultfmt="f%02i") @@ -1443,7 +1507,7 @@ M 33 21.99 assert_equal(mtest, ctrl) def test_single_dtype_w_explicit_names(self): - "Test single dtype w explicit names" + # Test single dtype w explicit names data = "0, 1, 2.3\n4, 5, 6.7" mtest = np.ndfromtxt(TextIO(data), delimiter=",", dtype=float, names="a, b, c") @@ -1452,7 +1516,7 @@ M 33 21.99 assert_equal(mtest, ctrl) def test_single_dtype_w_implicit_names(self): - "Test single dtype w implicit names" + # Test single dtype w implicit names data = "a, b, c\n0, 1, 2.3\n4, 5, 6.7" mtest = np.ndfromtxt(TextIO(data), delimiter=",", dtype=float, names=True) @@ -1461,7 +1525,7 @@ M 33 21.99 assert_equal(mtest, ctrl) def test_easy_structured_dtype(self): - "Test easy structured dtype" + # Test easy structured dtype data = "0, 1, 2.3\n4, 5, 6.7" mtest = np.ndfromtxt(TextIO(data), delimiter=",", dtype=(int, float, float), defaultfmt="f_%02i") @@ -1470,7 +1534,7 @@ M 33 21.99 assert_equal(mtest, ctrl) def test_autostrip(self): - "Test autostrip" + # Test autostrip data = "01/01/2003 , 1.3, abcde" kwargs = dict(delimiter=",", dtype=None) mtest = np.ndfromtxt(TextIO(data), **kwargs) @@ -1483,7 +1547,7 @@ M 33 21.99 assert_equal(mtest, ctrl) def test_replace_space(self): - "Test the 'replace_space' option" + # Test the 'replace_space' option txt = "A.A, B (B), C:C\n1, 2, 3.14" # Test default: replace ' ' by '_' and delete non-alphanum chars test = np.genfromtxt(TextIO(txt), @@ -1506,8 +1570,32 @@ M 33 21.99 ctrl = np.array((1, 2, 3.14), dtype=ctrl_dtype) assert_equal(test, ctrl) + def test_replace_space_known_dtype(self): + # Test the 'replace_space' (and related) options when dtype != None + txt = "A.A, B (B), C:C\n1, 2, 3" + # Test default: replace ' ' by '_' and delete non-alphanum chars + test = np.genfromtxt(TextIO(txt), + delimiter=",", names=True, dtype=int) + ctrl_dtype = [("AA", int), ("B_B", int), ("CC", int)] + ctrl = np.array((1, 2, 3), dtype=ctrl_dtype) + assert_equal(test, ctrl) + # Test: no replace, no delete + test = np.genfromtxt(TextIO(txt), + delimiter=",", names=True, dtype=int, + replace_space='', deletechars='') + ctrl_dtype = [("A.A", int), ("B (B)", int), ("C:C", int)] + ctrl = np.array((1, 2, 3), dtype=ctrl_dtype) + assert_equal(test, ctrl) + # Test: no delete (spaces are replaced by _) + test = np.genfromtxt(TextIO(txt), + delimiter=",", names=True, dtype=int, + deletechars='') + ctrl_dtype = [("A.A", int), ("B_(B)", int), ("C:C", int)] + ctrl = np.array((1, 2, 3), dtype=ctrl_dtype) + assert_equal(test, ctrl) + def test_incomplete_names(self): - "Test w/ incomplete names" + # Test w/ incomplete names data = "A,,C\n0,1,2\n3,4,5" kwargs = dict(delimiter=",", names=True) # w/ dtype=None @@ -1521,7 +1609,7 @@ M 33 21.99 test = np.ndfromtxt(TextIO(data), **kwargs) def test_names_auto_completion(self): - "Make sure that names are properly completed" + # Make sure that names are properly completed data = "1 2 3\n 4 5 6" test = np.genfromtxt(TextIO(data), dtype=(int, float, int), names="a") @@ -1530,7 +1618,7 @@ M 33 21.99 assert_equal(test, ctrl) def test_names_with_usecols_bug1636(self): - "Make sure we pick up the right names w/ usecols" + # Make sure we pick up the right names w/ usecols data = "A,B,C,D,E\n0,1,2,3,4\n0,1,2,3,4\n0,1,2,3,4" ctrl_names = ("A", "C", "E") test = np.genfromtxt(TextIO(data), @@ -1549,7 +1637,7 @@ M 33 21.99 assert_equal(test.dtype.names, ctrl_names) def test_fixed_width_names(self): - "Test fix-width w/ names" + # Test fix-width w/ names data = " A B C\n 0 1 2.3\n 45 67 9." kwargs = dict(delimiter=(5, 5, 4), names=True, dtype=None) ctrl = np.array([(0, 1, 2.3), (45, 67, 9.)], @@ -1564,7 +1652,7 @@ M 33 21.99 assert_equal(test, ctrl) def test_filling_values(self): - "Test missing values" + # Test missing values data = b"1, 2, 3\n1, , 5\n0, 6, \n" kwargs = dict(delimiter=",", dtype=None, filling_values=-999) ctrl = np.array([[1, 2, 3], [1, -999, 5], [0, 6, -999]], dtype=int) @@ -1633,9 +1721,64 @@ M 33 21.99 self.assertTrue(isinstance(test, np.recarray)) assert_equal(test, control) + def test_max_rows(self): + # Test the `max_rows` keyword argument. + data = '1 2\n3 4\n5 6\n7 8\n9 10\n' + txt = TextIO(data) + a1 = np.genfromtxt(txt, max_rows=3) + a2 = np.genfromtxt(txt) + assert_equal(a1, [[1, 2], [3, 4], [5, 6]]) + assert_equal(a2, [[7, 8], [9, 10]]) + + # max_rows must be at least 1. + assert_raises(ValueError, np.genfromtxt, TextIO(data), max_rows=0) + + # An input with several invalid rows. + data = '1 1\n2 2\n0 \n3 3\n4 4\n5 \n6 \n7 \n' + + test = np.genfromtxt(TextIO(data), max_rows=2) + control = np.array([[1., 1.], [2., 2.]]) + assert_equal(test, control) + + # Test keywords conflict + assert_raises(ValueError, np.genfromtxt, TextIO(data), skip_footer=1, + max_rows=4) + + # Test with invalid value + assert_raises(ValueError, np.genfromtxt, TextIO(data), max_rows=4) + + # Test with invalid not raise + with suppress_warnings() as sup: + sup.filter(ConversionWarning) + + test = np.genfromtxt(TextIO(data), max_rows=4, invalid_raise=False) + control = np.array([[1., 1.], [2., 2.], [3., 3.], [4., 4.]]) + assert_equal(test, control) + + test = np.genfromtxt(TextIO(data), max_rows=5, invalid_raise=False) + control = np.array([[1., 1.], [2., 2.], [3., 3.], [4., 4.]]) + assert_equal(test, control) + + # Structured array with field names. + data = 'a b\n#c d\n1 1\n2 2\n#0 \n3 3\n4 4\n5 5\n' + + # Test with header, names and comments + txt = TextIO(data) + test = np.genfromtxt(txt, skip_header=1, max_rows=3, names=True) + control = np.array([(1.0, 1.0), (2.0, 2.0), (3.0, 3.0)], + dtype=[('c', '<f8'), ('d', '<f8')]) + assert_equal(test, control) + # To continue reading the same "file", don't use skip_header or + # names, and use the previously determined dtype. + test = np.genfromtxt(txt, max_rows=None, dtype=test.dtype) + control = np.array([(4.0, 4.0), (5.0, 5.0)], + dtype=[('c', '<f8'), ('d', '<f8')]) + assert_equal(test, control) + def test_gft_using_filename(self): - # Test that we can load data from a filename as well as a file object - wanted = np.arange(6).reshape((2, 3)) + # Test that we can load data from a filename as well as a file + # object + tgt = np.arange(6).reshape((2, 3)) if sys.version_info[0] >= 3: # python 3k is known to fail for '\r' linesep = ('\n', '\r\n') @@ -1644,15 +1787,11 @@ M 33 21.99 for sep in linesep: data = '0 1 2' + sep + '3 4 5' - f, name = mkstemp() - # We can't use NamedTemporaryFile on windows, because we cannot - # reopen the file. - try: - os.write(f, asbytes(data)) - assert_array_equal(np.genfromtxt(name), wanted) - finally: - os.close(f) - os.unlink(name) + with temppath() as name: + with open(name, 'w') as f: + f.write(data) + res = np.genfromtxt(name) + assert_array_equal(res, tgt) def test_gft_using_generator(self): # gft doesn't work with unicode. @@ -1663,6 +1802,133 @@ M 33 21.99 res = np.genfromtxt(count()) assert_array_equal(res, np.arange(10)) + def test_auto_dtype_largeint(self): + # Regression test for numpy/numpy#5635 whereby large integers could + # cause OverflowErrors. + + # Test the automatic definition of the output dtype + # + # 2**66 = 73786976294838206464 => should convert to float + # 2**34 = 17179869184 => should convert to int64 + # 2**10 = 1024 => should convert to int (int32 on 32-bit systems, + # int64 on 64-bit systems) + + data = TextIO('73786976294838206464 17179869184 1024') + + test = np.ndfromtxt(data, dtype=None) + + assert_equal(test.dtype.names, ['f0', 'f1', 'f2']) + + assert_(test.dtype['f0'] == np.float) + assert_(test.dtype['f1'] == np.int64) + assert_(test.dtype['f2'] == np.integer) + + assert_allclose(test['f0'], 73786976294838206464.) + assert_equal(test['f1'], 17179869184) + assert_equal(test['f2'], 1024) + + +class TestPathUsage(TestCase): + # Test that pathlib.Path can be used + @np.testing.dec.skipif(Path is None, "No pathlib.Path") + def test_loadtxt(self): + with temppath(suffix='.txt') as path: + path = Path(path) + a = np.array([[1.1, 2], [3, 4]]) + np.savetxt(path, a) + x = np.loadtxt(path) + assert_array_equal(x, a) + + @np.testing.dec.skipif(Path is None, "No pathlib.Path") + def test_save_load(self): + # Test that pathlib.Path instances can be used with savez. + with temppath(suffix='.npy') as path: + path = Path(path) + a = np.array([[1, 2], [3, 4]], int) + np.save(path, a) + data = np.load(path) + assert_array_equal(data, a) + + @np.testing.dec.skipif(Path is None, "No pathlib.Path") + def test_savez_load(self): + # Test that pathlib.Path instances can be used with savez. + with temppath(suffix='.npz') as path: + path = Path(path) + np.savez(path, lab='place holder') + with np.load(path) as data: + assert_array_equal(data['lab'], 'place holder') + + @np.testing.dec.skipif(Path is None, "No pathlib.Path") + def test_savez_compressed_load(self): + # Test that pathlib.Path instances can be used with savez. + with temppath(suffix='.npz') as path: + path = Path(path) + np.savez_compressed(path, lab='place holder') + data = np.load(path) + assert_array_equal(data['lab'], 'place holder') + data.close() + + @np.testing.dec.skipif(Path is None, "No pathlib.Path") + def test_genfromtxt(self): + with temppath(suffix='.txt') as path: + path = Path(path) + a = np.array([(1, 2), (3, 4)]) + np.savetxt(path, a) + data = np.genfromtxt(path) + assert_array_equal(a, data) + + @np.testing.dec.skipif(Path is None, "No pathlib.Path") + def test_ndfromtxt(self): + # Test outputing a standard ndarray + with temppath(suffix='.txt') as path: + path = Path(path) + with path.open('w') as f: + f.write(u'1 2\n3 4') + + control = np.array([[1, 2], [3, 4]], dtype=int) + test = np.ndfromtxt(path, dtype=int) + assert_array_equal(test, control) + + @np.testing.dec.skipif(Path is None, "No pathlib.Path") + def test_mafromtxt(self): + # From `test_fancy_dtype_alt` above + with temppath(suffix='.txt') as path: + path = Path(path) + with path.open('w') as f: + f.write(u'1,2,3.0\n4,5,6.0\n') + + test = np.mafromtxt(path, delimiter=',') + control = ma.array([(1.0, 2.0, 3.0), (4.0, 5.0, 6.0)]) + assert_equal(test, control) + + @np.testing.dec.skipif(Path is None, "No pathlib.Path") + def test_recfromtxt(self): + with temppath(suffix='.txt') as path: + path = Path(path) + with path.open('w') as f: + f.write(u'A,B\n0,1\n2,3') + + kwargs = dict(delimiter=",", missing_values="N/A", names=True) + test = np.recfromtxt(path, **kwargs) + control = np.array([(0, 1), (2, 3)], + dtype=[('A', np.int), ('B', np.int)]) + self.assertTrue(isinstance(test, np.recarray)) + assert_equal(test, control) + + @np.testing.dec.skipif(Path is None, "No pathlib.Path") + def test_recfromcsv(self): + with temppath(suffix='.txt') as path: + path = Path(path) + with path.open('w') as f: + f.write(u'A,B\n0,1\n2,3') + + kwargs = dict(missing_values="N/A", names=True, case_sensitive=True) + test = np.recfromcsv(path, dtype=None, **kwargs) + control = np.array([(0, 1), (2, 3)], + dtype=[('A', np.int), ('B', np.int)]) + self.assertTrue(isinstance(test, np.recarray)) + assert_equal(test, control) + def test_gzip_load(): a = np.random.random((5, 5)) @@ -1688,16 +1954,15 @@ def test_gzip_loadtxt(): g = gzip.GzipFile(fileobj=s, mode='w') g.write(b'1 2 3\n') g.close() + s.seek(0) + with temppath(suffix='.gz') as name: + with open(name, 'wb') as f: + f.write(s.read()) + res = np.loadtxt(name) + s.close() - f, name = mkstemp(suffix='.gz') - try: - os.write(f, s.read()) - s.close() - assert_array_equal(np.loadtxt(name), [1, 2, 3]) - finally: - os.close(f) - os.unlink(name) + assert_array_equal(res, [1, 2, 3]) def test_gzip_loadtxt_from_string(): @@ -1746,12 +2011,17 @@ def test_load_refcount(): np.savez(f, [1, 2, 3]) f.seek(0) - gc.collect() - n_before = len(gc.get_objects()) - np.load(f) - n_after = len(gc.get_objects()) - - assert_equal(n_before, n_after) + assert_(gc.isenabled()) + gc.disable() + try: + gc.collect() + np.load(f) + # gc.collect returns the number of unreachable objects in cycles that + # were found -- we are checking that no cycles were created by np.load + n_objects_in_cycles = gc.collect() + finally: + gc.enable() + assert_equal(n_objects_in_cycles, 0) if __name__ == "__main__": run_module_suite() diff --git a/numpy/lib/tests/test_nanfunctions.py b/numpy/lib/tests/test_nanfunctions.py index 35ae86c20..06c0953b5 100644 --- a/numpy/lib/tests/test_nanfunctions.py +++ b/numpy/lib/tests/test_nanfunctions.py @@ -5,7 +5,7 @@ import warnings import numpy as np from numpy.testing import ( run_module_suite, TestCase, assert_, assert_equal, assert_almost_equal, - assert_raises, assert_array_equal + assert_no_warnings, assert_raises, assert_array_equal, suppress_warnings ) @@ -22,6 +22,18 @@ _rdat = [np.array([0.6244, 0.2692, 0.0116, 0.1170]), np.array([0.1042, -0.5954]), np.array([0.1610, 0.1859, 0.3146])] +# Rows of _ndat with nans converted to ones +_ndat_ones = np.array([[0.6244, 1.0, 0.2692, 0.0116, 1.0, 0.1170], + [0.5351, -0.9403, 1.0, 0.2100, 0.4759, 0.2833], + [1.0, 1.0, 1.0, 0.1042, 1.0, -0.5954], + [0.1610, 1.0, 1.0, 0.1859, 0.3146, 1.0]]) + +# Rows of _ndat with nans converted to zeros +_ndat_zeros = np.array([[0.6244, 0.0, 0.2692, 0.0116, 0.0, 0.1170], + [0.5351, -0.9403, 0.0, 0.2100, 0.4759, 0.2833], + [0.0, 0.0, 0.0, 0.1042, 0.0, -0.5954], + [0.1610, 0.0, 0.0, 0.1859, 0.3146, 0.0]]) + class TestNanFunctions_MinMax(TestCase): @@ -155,8 +167,8 @@ class TestNanFunctions_ArgminArgmax(TestCase): def test_result_values(self): for f, fcmp in zip(self.nanfuncs, [np.greater, np.less]): for row in _ndat: - with warnings.catch_warnings(record=True): - warnings.simplefilter('always') + with suppress_warnings() as sup: + sup.filter(RuntimeWarning, "invalid value encountered in") ind = f(row) val = row[ind] # comparing with NaN is tricky as the result @@ -236,6 +248,21 @@ class TestNanFunctions_IntTypes(TestCase): for mat in self.integer_arrays(): assert_equal(np.nansum(mat), tgt) + def test_nanprod(self): + tgt = np.prod(self.mat) + for mat in self.integer_arrays(): + assert_equal(np.nanprod(mat), tgt) + + def test_nancumsum(self): + tgt = np.cumsum(self.mat) + for mat in self.integer_arrays(): + assert_equal(np.nancumsum(mat), tgt) + + def test_nancumprod(self): + tgt = np.cumprod(self.mat) + for mat in self.integer_arrays(): + assert_equal(np.nancumprod(mat), tgt) + def test_nanmean(self): tgt = np.mean(self.mat) for mat in self.integer_arrays(): @@ -260,70 +287,108 @@ class TestNanFunctions_IntTypes(TestCase): assert_equal(np.nanstd(mat, ddof=1), tgt) -class TestNanFunctions_Sum(TestCase): - +class SharedNanFunctionsTestsMixin(object): def test_mutation(self): # Check that passed array is not modified. ndat = _ndat.copy() - np.nansum(ndat) - assert_equal(ndat, _ndat) + for f in self.nanfuncs: + f(ndat) + assert_equal(ndat, _ndat) def test_keepdims(self): mat = np.eye(3) - for axis in [None, 0, 1]: - tgt = np.sum(mat, axis=axis, keepdims=True) - res = np.nansum(mat, axis=axis, keepdims=True) - assert_(res.ndim == tgt.ndim) + for nf, rf in zip(self.nanfuncs, self.stdfuncs): + for axis in [None, 0, 1]: + tgt = rf(mat, axis=axis, keepdims=True) + res = nf(mat, axis=axis, keepdims=True) + assert_(res.ndim == tgt.ndim) def test_out(self): mat = np.eye(3) - resout = np.zeros(3) - tgt = np.sum(mat, axis=1) - res = np.nansum(mat, axis=1, out=resout) - assert_almost_equal(res, resout) - assert_almost_equal(res, tgt) + for nf, rf in zip(self.nanfuncs, self.stdfuncs): + resout = np.zeros(3) + tgt = rf(mat, axis=1) + res = nf(mat, axis=1, out=resout) + assert_almost_equal(res, resout) + assert_almost_equal(res, tgt) def test_dtype_from_dtype(self): mat = np.eye(3) codes = 'efdgFDG' - for c in codes: - tgt = np.sum(mat, dtype=np.dtype(c), axis=1).dtype.type - res = np.nansum(mat, dtype=np.dtype(c), axis=1).dtype.type - assert_(res is tgt) - # scalar case - tgt = np.sum(mat, dtype=np.dtype(c), axis=None).dtype.type - res = np.nansum(mat, dtype=np.dtype(c), axis=None).dtype.type - assert_(res is tgt) + for nf, rf in zip(self.nanfuncs, self.stdfuncs): + for c in codes: + with suppress_warnings() as sup: + if nf in {np.nanstd, np.nanvar} and c in 'FDG': + # Giving the warning is a small bug, see gh-8000 + sup.filter(np.ComplexWarning) + tgt = rf(mat, dtype=np.dtype(c), axis=1).dtype.type + res = nf(mat, dtype=np.dtype(c), axis=1).dtype.type + assert_(res is tgt) + # scalar case + tgt = rf(mat, dtype=np.dtype(c), axis=None).dtype.type + res = nf(mat, dtype=np.dtype(c), axis=None).dtype.type + assert_(res is tgt) def test_dtype_from_char(self): mat = np.eye(3) codes = 'efdgFDG' - for c in codes: - tgt = np.sum(mat, dtype=c, axis=1).dtype.type - res = np.nansum(mat, dtype=c, axis=1).dtype.type - assert_(res is tgt) - # scalar case - tgt = np.sum(mat, dtype=c, axis=None).dtype.type - res = np.nansum(mat, dtype=c, axis=None).dtype.type - assert_(res is tgt) + for nf, rf in zip(self.nanfuncs, self.stdfuncs): + for c in codes: + with suppress_warnings() as sup: + if nf in {np.nanstd, np.nanvar} and c in 'FDG': + # Giving the warning is a small bug, see gh-8000 + sup.filter(np.ComplexWarning) + tgt = rf(mat, dtype=c, axis=1).dtype.type + res = nf(mat, dtype=c, axis=1).dtype.type + assert_(res is tgt) + # scalar case + tgt = rf(mat, dtype=c, axis=None).dtype.type + res = nf(mat, dtype=c, axis=None).dtype.type + assert_(res is tgt) def test_dtype_from_input(self): codes = 'efdgFDG' - for c in codes: - mat = np.eye(3, dtype=c) - tgt = np.sum(mat, axis=1).dtype.type - res = np.nansum(mat, axis=1).dtype.type - assert_(res is tgt) - # scalar case - tgt = np.sum(mat, axis=None).dtype.type - res = np.nansum(mat, axis=None).dtype.type - assert_(res is tgt) + for nf, rf in zip(self.nanfuncs, self.stdfuncs): + for c in codes: + mat = np.eye(3, dtype=c) + tgt = rf(mat, axis=1).dtype.type + res = nf(mat, axis=1).dtype.type + assert_(res is tgt, "res %s, tgt %s" % (res, tgt)) + # scalar case + tgt = rf(mat, axis=None).dtype.type + res = nf(mat, axis=None).dtype.type + assert_(res is tgt) def test_result_values(self): - tgt = [np.sum(d) for d in _rdat] - res = np.nansum(_ndat, axis=1) + for nf, rf in zip(self.nanfuncs, self.stdfuncs): + tgt = [rf(d) for d in _rdat] + res = nf(_ndat, axis=1) assert_almost_equal(res, tgt) + def test_scalar(self): + for f in self.nanfuncs: + assert_(f(0.) == 0.) + + def test_matrices(self): + # Check that it works and that type and + # shape are preserved + mat = np.matrix(np.eye(3)) + for f in self.nanfuncs: + res = f(mat, axis=0) + assert_(isinstance(res, np.matrix)) + assert_(res.shape == (1, 3)) + res = f(mat, axis=1) + assert_(isinstance(res, np.matrix)) + assert_(res.shape == (3, 1)) + res = f(mat) + assert_(np.isscalar(res)) + + +class TestNanFunctions_SumProd(TestCase, SharedNanFunctionsTestsMixin): + + nanfuncs = [np.nansum, np.nanprod] + stdfuncs = [np.sum, np.prod] + def test_allnans(self): # Check for FutureWarning with warnings.catch_warnings(record=True) as w: @@ -340,113 +405,118 @@ class TestNanFunctions_Sum(TestCase): assert_(len(w) == 0, 'unwanted warning raised') def test_empty(self): - mat = np.zeros((0, 3)) - tgt = [0]*3 - res = np.nansum(mat, axis=0) - assert_equal(res, tgt) - tgt = [] - res = np.nansum(mat, axis=1) - assert_equal(res, tgt) - tgt = 0 - res = np.nansum(mat, axis=None) - assert_equal(res, tgt) + for f, tgt_value in zip([np.nansum, np.nanprod], [0, 1]): + mat = np.zeros((0, 3)) + tgt = [tgt_value]*3 + res = f(mat, axis=0) + assert_equal(res, tgt) + tgt = [] + res = f(mat, axis=1) + assert_equal(res, tgt) + tgt = tgt_value + res = f(mat, axis=None) + assert_equal(res, tgt) - def test_scalar(self): - assert_(np.nansum(0.) == 0.) + +class TestNanFunctions_CumSumProd(TestCase, SharedNanFunctionsTestsMixin): + + nanfuncs = [np.nancumsum, np.nancumprod] + stdfuncs = [np.cumsum, np.cumprod] + + def test_allnans(self): + for f, tgt_value in zip(self.nanfuncs, [0, 1]): + # Unlike other nan-functions, sum/prod/cumsum/cumprod don't warn on all nan input + with assert_no_warnings(): + res = f([np.nan]*3, axis=None) + tgt = tgt_value*np.ones((3)) + assert_(np.array_equal(res, tgt), 'result is not %s * np.ones((3))' % (tgt_value)) + # Check scalar + res = f(np.nan) + tgt = tgt_value*np.ones((1)) + assert_(np.array_equal(res, tgt), 'result is not %s * np.ones((1))' % (tgt_value)) + # Check there is no warning for not all-nan + f([0]*3, axis=None) + + def test_empty(self): + for f, tgt_value in zip(self.nanfuncs, [0, 1]): + mat = np.zeros((0, 3)) + tgt = tgt_value*np.ones((0, 3)) + res = f(mat, axis=0) + assert_equal(res, tgt) + tgt = mat + res = f(mat, axis=1) + assert_equal(res, tgt) + tgt = np.zeros((0)) + res = f(mat, axis=None) + assert_equal(res, tgt) + + def test_keepdims(self): + for f, g in zip(self.nanfuncs, self.stdfuncs): + mat = np.eye(3) + for axis in [None, 0, 1]: + tgt = f(mat, axis=axis, out=None) + res = g(mat, axis=axis, out=None) + assert_(res.ndim == tgt.ndim) + + for f in self.nanfuncs: + d = np.ones((3, 5, 7, 11)) + # Randomly set some elements to NaN: + rs = np.random.RandomState(0) + d[rs.rand(*d.shape) < 0.5] = np.nan + res = f(d, axis=None) + assert_equal(res.shape, (1155,)) + for axis in np.arange(4): + res = f(d, axis=axis) + assert_equal(res.shape, (3, 5, 7, 11)) def test_matrices(self): # Check that it works and that type and # shape are preserved mat = np.matrix(np.eye(3)) - res = np.nansum(mat, axis=0) - assert_(isinstance(res, np.matrix)) - assert_(res.shape == (1, 3)) - res = np.nansum(mat, axis=1) - assert_(isinstance(res, np.matrix)) - assert_(res.shape == (3, 1)) - res = np.nansum(mat) - assert_(np.isscalar(res)) + for f in self.nanfuncs: + for axis in np.arange(2): + res = f(mat, axis=axis) + assert_(isinstance(res, np.matrix)) + assert_(res.shape == (3, 3)) + res = f(mat) + assert_(res.shape == (1, 3*3)) + + def test_result_values(self): + for axis in (-2, -1, 0, 1, None): + tgt = np.cumprod(_ndat_ones, axis=axis) + res = np.nancumprod(_ndat, axis=axis) + assert_almost_equal(res, tgt) + tgt = np.cumsum(_ndat_zeros,axis=axis) + res = np.nancumsum(_ndat, axis=axis) + assert_almost_equal(res, tgt) + + def test_out(self): + mat = np.eye(3) + for nf, rf in zip(self.nanfuncs, self.stdfuncs): + resout = np.eye(3) + for axis in (-2, -1, 0, 1): + tgt = rf(mat, axis=axis) + res = nf(mat, axis=axis, out=resout) + assert_almost_equal(res, resout) + assert_almost_equal(res, tgt) -class TestNanFunctions_MeanVarStd(TestCase): +class TestNanFunctions_MeanVarStd(TestCase, SharedNanFunctionsTestsMixin): nanfuncs = [np.nanmean, np.nanvar, np.nanstd] stdfuncs = [np.mean, np.var, np.std] - def test_mutation(self): - # Check that passed array is not modified. - ndat = _ndat.copy() - for f in self.nanfuncs: - f(ndat) - assert_equal(ndat, _ndat) - def test_dtype_error(self): for f in self.nanfuncs: - for dtype in [np.bool_, np.int_, np.object]: - assert_raises(TypeError, f, _ndat, axis=1, dtype=np.int) + for dtype in [np.bool_, np.int_, np.object_]: + assert_raises(TypeError, f, _ndat, axis=1, dtype=dtype) def test_out_dtype_error(self): for f in self.nanfuncs: - for dtype in [np.bool_, np.int_, np.object]: + for dtype in [np.bool_, np.int_, np.object_]: out = np.empty(_ndat.shape[0], dtype=dtype) assert_raises(TypeError, f, _ndat, axis=1, out=out) - def test_keepdims(self): - mat = np.eye(3) - for nf, rf in zip(self.nanfuncs, self.stdfuncs): - for axis in [None, 0, 1]: - tgt = rf(mat, axis=axis, keepdims=True) - res = nf(mat, axis=axis, keepdims=True) - assert_(res.ndim == tgt.ndim) - - def test_out(self): - mat = np.eye(3) - for nf, rf in zip(self.nanfuncs, self.stdfuncs): - resout = np.zeros(3) - tgt = rf(mat, axis=1) - res = nf(mat, axis=1, out=resout) - assert_almost_equal(res, resout) - assert_almost_equal(res, tgt) - - def test_dtype_from_dtype(self): - mat = np.eye(3) - codes = 'efdgFDG' - for nf, rf in zip(self.nanfuncs, self.stdfuncs): - for c in codes: - tgt = rf(mat, dtype=np.dtype(c), axis=1).dtype.type - res = nf(mat, dtype=np.dtype(c), axis=1).dtype.type - assert_(res is tgt) - # scalar case - tgt = rf(mat, dtype=np.dtype(c), axis=None).dtype.type - res = nf(mat, dtype=np.dtype(c), axis=None).dtype.type - assert_(res is tgt) - - def test_dtype_from_char(self): - mat = np.eye(3) - codes = 'efdgFDG' - for nf, rf in zip(self.nanfuncs, self.stdfuncs): - for c in codes: - tgt = rf(mat, dtype=c, axis=1).dtype.type - res = nf(mat, dtype=c, axis=1).dtype.type - assert_(res is tgt) - # scalar case - tgt = rf(mat, dtype=c, axis=None).dtype.type - res = nf(mat, dtype=c, axis=None).dtype.type - assert_(res is tgt) - - def test_dtype_from_input(self): - codes = 'efdgFDG' - for nf, rf in zip(self.nanfuncs, self.stdfuncs): - for c in codes: - mat = np.eye(3, dtype=c) - tgt = rf(mat, axis=1).dtype.type - res = nf(mat, axis=1).dtype.type - assert_(res is tgt, "res %s, tgt %s" % (res, tgt)) - # scalar case - tgt = rf(mat, axis=None).dtype.type - res = nf(mat, axis=None).dtype.type - assert_(res is tgt) - def test_ddof(self): nanfuncs = [np.nanvar, np.nanstd] stdfuncs = [np.var, np.std] @@ -462,22 +532,16 @@ class TestNanFunctions_MeanVarStd(TestCase): dsize = [len(d) for d in _rdat] for nf, rf in zip(nanfuncs, stdfuncs): for ddof in range(5): - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always') + with suppress_warnings() as sup: + sup.record(RuntimeWarning) + sup.filter(np.ComplexWarning) tgt = [ddof >= d for d in dsize] res = nf(_ndat, axis=1, ddof=ddof) assert_equal(np.isnan(res), tgt) if any(tgt): - assert_(len(w) == 1) - assert_(issubclass(w[0].category, RuntimeWarning)) + assert_(len(sup.log) == 1) else: - assert_(len(w) == 0) - - def test_result_values(self): - for nf, rf in zip(self.nanfuncs, self.stdfuncs): - tgt = [rf(d) for d in _rdat] - res = nf(_ndat, axis=1) - assert_almost_equal(res, tgt) + assert_(len(sup.log) == 0) def test_allnans(self): mat = np.array([np.nan]*9).reshape(3, 3) @@ -508,24 +572,6 @@ class TestNanFunctions_MeanVarStd(TestCase): assert_equal(f(mat, axis=axis), np.zeros([])) assert_(len(w) == 0) - def test_scalar(self): - for f in self.nanfuncs: - assert_(f(0.) == 0.) - - def test_matrices(self): - # Check that it works and that type and - # shape are preserved - mat = np.matrix(np.eye(3)) - for f in self.nanfuncs: - res = f(mat, axis=0) - assert_(isinstance(res, np.matrix)) - assert_(res.shape == (1, 3)) - res = f(mat, axis=1) - assert_(isinstance(res, np.matrix)) - assert_(res.shape == (3, 1)) - res = f(mat) - assert_(np.isscalar(res)) - class TestNanFunctions_Median(TestCase): @@ -547,8 +593,8 @@ class TestNanFunctions_Median(TestCase): w = np.random.random((4, 200)) * np.array(d.shape)[:, None] w = w.astype(np.intp) d[tuple(w)] = np.nan - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always', RuntimeWarning) + with suppress_warnings() as sup: + sup.filter(RuntimeWarning) res = np.nanmedian(d, axis=None, keepdims=True) assert_equal(res.shape, (1, 1, 1, 1)) res = np.nanmedian(d, axis=(0, 1), keepdims=True) @@ -604,21 +650,20 @@ class TestNanFunctions_Median(TestCase): def test_allnans(self): mat = np.array([np.nan]*9).reshape(3, 3) for axis in [None, 0, 1]: - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always') + with suppress_warnings() as sup: + sup.record(RuntimeWarning) + assert_(np.isnan(np.nanmedian(mat, axis=axis)).all()) if axis is None: - assert_(len(w) == 1) + assert_(len(sup.log) == 1) else: - assert_(len(w) == 3) - assert_(issubclass(w[0].category, RuntimeWarning)) + assert_(len(sup.log) == 3) # Check scalar assert_(np.isnan(np.nanmedian(np.nan))) if axis is None: - assert_(len(w) == 2) + assert_(len(sup.log) == 2) else: - assert_(len(w) == 4) - assert_(issubclass(w[0].category, RuntimeWarning)) + assert_(len(sup.log) == 4) def test_empty(self): mat = np.zeros((0, 3)) @@ -646,8 +691,8 @@ class TestNanFunctions_Median(TestCase): assert_raises(ValueError, np.nanmedian, d, axis=(1, 1)) def test_float_special(self): - with warnings.catch_warnings(record=True): - warnings.simplefilter('ignore', RuntimeWarning) + with suppress_warnings() as sup: + sup.filter(RuntimeWarning) a = np.array([[np.inf, np.nan], [np.nan, np.nan]]) assert_equal(np.nanmedian(a, axis=0), [np.inf, np.nan]) assert_equal(np.nanmedian(a, axis=1), [np.inf, np.nan]) @@ -684,8 +729,8 @@ class TestNanFunctions_Percentile(TestCase): w = np.random.random((4, 200)) * np.array(d.shape)[:, None] w = w.astype(np.intp) d[tuple(w)] = np.nan - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always', RuntimeWarning) + with suppress_warnings() as sup: + sup.filter(RuntimeWarning) res = np.nanpercentile(d, 90, axis=None, keepdims=True) assert_equal(res.shape, (1, 1, 1, 1)) res = np.nanpercentile(d, 90, axis=(0, 1), keepdims=True) @@ -721,7 +766,8 @@ class TestNanFunctions_Percentile(TestCase): tgt = [np.percentile(d, 28) for d in _rdat] res = np.nanpercentile(_ndat, 28, axis=1) assert_almost_equal(res, tgt) - tgt = [np.percentile(d, (28, 98)) for d in _rdat] + # Transpose the array to fit the output convention of numpy.percentile + tgt = np.transpose([np.percentile(d, (28, 98)) for d in _rdat]) res = np.nanpercentile(_ndat, (28, 98), axis=1) assert_almost_equal(res, tgt) @@ -769,6 +815,32 @@ class TestNanFunctions_Percentile(TestCase): assert_raises(IndexError, np.nanpercentile, d, q=5, axis=(0, 4)) assert_raises(ValueError, np.nanpercentile, d, q=5, axis=(1, 1)) + def test_multiple_percentiles(self): + perc = [50, 100] + mat = np.ones((4, 3)) + nan_mat = np.nan * mat + # For checking consistency in higher dimensional case + large_mat = np.ones((3, 4, 5)) + large_mat[:, 0:2:4, :] = 0 + large_mat[:, :, 3:] *= 2 + for axis in [None, 0, 1]: + for keepdim in [False, True]: + with suppress_warnings() as sup: + sup.filter(RuntimeWarning, "All-NaN slice encountered") + val = np.percentile(mat, perc, axis=axis, keepdims=keepdim) + nan_val = np.nanpercentile(nan_mat, perc, axis=axis, + keepdims=keepdim) + assert_equal(nan_val.shape, val.shape) + + val = np.percentile(large_mat, perc, axis=axis, + keepdims=keepdim) + nan_val = np.nanpercentile(large_mat, perc, axis=axis, + keepdims=keepdim) + assert_equal(nan_val, val) + + megamat = np.ones((3, 4, 5, 6)) + assert_equal(np.nanpercentile(megamat, perc, axis=(1, 2)).shape, (2, 3, 6)) + if __name__ == "__main__": run_module_suite() diff --git a/numpy/lib/tests/test_packbits.py b/numpy/lib/tests/test_packbits.py new file mode 100644 index 000000000..0de084ef9 --- /dev/null +++ b/numpy/lib/tests/test_packbits.py @@ -0,0 +1,27 @@ +from __future__ import division, absolute_import, print_function + +import numpy as np +from numpy.testing import assert_array_equal, assert_equal, assert_raises + + +def test_packbits(): + # Copied from the docstring. + a = [[[1, 0, 1], [0, 1, 0]], + [[1, 1, 0], [0, 0, 1]]] + for dtype in [np.bool, np.uint8, np.int]: + arr = np.array(a, dtype=dtype) + b = np.packbits(arr, axis=-1) + assert_equal(b.dtype, np.uint8) + assert_array_equal(b, np.array([[[160], [64]], [[192], [32]]])) + + assert_raises(TypeError, np.packbits, np.array(a, dtype=float)) + + +def test_unpackbits(): + # Copied from the docstring. + a = np.array([[2], [7], [23]], dtype=np.uint8) + b = np.unpackbits(a, axis=1) + assert_equal(b.dtype, np.uint8) + assert_array_equal(b, np.array([[0, 0, 0, 0, 0, 0, 1, 0], + [0, 0, 0, 0, 0, 1, 1, 1], + [0, 0, 0, 1, 0, 1, 1, 1]])) diff --git a/numpy/lib/tests/test_polynomial.py b/numpy/lib/tests/test_polynomial.py index 5c15941e6..00dffd3d3 100644 --- a/numpy/lib/tests/test_polynomial.py +++ b/numpy/lib/tests/test_polynomial.py @@ -81,7 +81,7 @@ poly1d([ 2.]) import numpy as np from numpy.testing import ( run_module_suite, TestCase, assert_, assert_equal, assert_array_equal, - assert_almost_equal, rundocs + assert_almost_equal, assert_array_almost_equal, assert_raises, rundocs ) @@ -89,6 +89,30 @@ class TestDocs(TestCase): def test_doctests(self): return rundocs() + def test_poly(self): + assert_array_almost_equal(np.poly([3, -np.sqrt(2), np.sqrt(2)]), + [1, -3, -2, 6]) + + # From matlab docs + A = [[1, 2, 3], [4, 5, 6], [7, 8, 0]] + assert_array_almost_equal(np.poly(A), [1, -6, -72, -27]) + + # Should produce real output for perfect conjugates + assert_(np.isrealobj(np.poly([+1.082j, +2.613j, -2.613j, -1.082j]))) + assert_(np.isrealobj(np.poly([0+1j, -0+-1j, 1+2j, + 1-2j, 1.+3.5j, 1-3.5j]))) + assert_(np.isrealobj(np.poly([1j, -1j, 1+2j, 1-2j, 1+3j, 1-3.j]))) + assert_(np.isrealobj(np.poly([1j, -1j, 1+2j, 1-2j]))) + assert_(np.isrealobj(np.poly([1j, -1j, 2j, -2j]))) + assert_(np.isrealobj(np.poly([1j, -1j]))) + assert_(np.isrealobj(np.poly([1, -1]))) + + assert_(np.iscomplexobj(np.poly([1j, -1.0000001j]))) + + np.random.seed(42) + a = np.random.randn(100) + 1j*np.random.randn(100) + assert_(np.isrealobj(np.poly(np.concatenate((a, np.conjugate(a)))))) + def test_roots(self): assert_array_equal(np.roots([1, 0, 0]), [0, 0]) @@ -111,6 +135,12 @@ class TestDocs(TestCase): err = [1, -1, 1, -1, 1, -1, 1] weights = np.arange(8, 1, -1)**2/7.0 + # Check exception when too few points for variance estimate. Note that + # the Bayesian estimate requires the number of data points to exceed + # degree + 3. + assert_raises(ValueError, np.polyfit, + [0, 1, 3], [0, 1, 3], deg=0, cov=True) + # check 1D case m, cov = np.polyfit(x, y+err, 2, cov=True) est = [3.8571, 0.2857, 1.619] diff --git a/numpy/lib/tests/test_recfunctions.py b/numpy/lib/tests/test_recfunctions.py index 51a2077eb..699a04716 100644 --- a/numpy/lib/tests/test_recfunctions.py +++ b/numpy/lib/tests/test_recfunctions.py @@ -3,9 +3,8 @@ from __future__ import division, absolute_import, print_function import numpy as np import numpy.ma as ma from numpy.ma.mrecords import MaskedRecords -from numpy.ma.testutils import ( - run_module_suite, TestCase, assert_, assert_equal - ) +from numpy.ma.testutils import assert_equal +from numpy.testing import TestCase, run_module_suite, assert_ from numpy.lib.recfunctions import ( drop_fields, rename_fields, get_fieldstructure, recursive_fill_fields, find_duplicates, merge_arrays, append_fields, stack_arrays, join_by @@ -700,6 +699,26 @@ class TestJoinBy2(TestCase): assert_equal(test.dtype, control.dtype) assert_equal(test, control) +class TestAppendFieldsObj(TestCase): + """ + Test append_fields with arrays containing objects + """ + # https://github.com/numpy/numpy/issues/2346 + + def setUp(self): + from datetime import date + self.data = dict(obj=date(2000, 1, 1)) + + def test_append_to_objects(self): + "Test append_fields when the base array contains objects" + obj = self.data['obj'] + x = np.array([(obj, 1.), (obj, 2.)], + dtype=[('A', object), ('B', float)]) + y = np.array([10, 20], dtype=int) + test = append_fields(x, 'C', data=y, usemask=False) + control = np.array([(obj, 1.0, 10), (obj, 2.0, 20)], + dtype=[('A', object), ('B', float), ('C', int)]) + assert_equal(test, control) if __name__ == '__main__': run_module_suite() diff --git a/numpy/lib/tests/test_regression.py b/numpy/lib/tests/test_regression.py index 00fa3f195..ee50dcfa4 100644 --- a/numpy/lib/tests/test_regression.py +++ b/numpy/lib/tests/test_regression.py @@ -85,10 +85,6 @@ class TestRegression(TestCase): assert_(x != y) assert_(x == x) - def test_mem_insert(self, level=rlevel): - # Ticket #572 - np.lib.place(1, 1, 1) - def test_polyfit_build(self): # Ticket #628 ref = [-1.06123820e-06, 5.70886914e-04, -1.13822012e-01, diff --git a/numpy/lib/tests/test_shape_base.py b/numpy/lib/tests/test_shape_base.py index 23f3edfbe..2eb4a809d 100644 --- a/numpy/lib/tests/test_shape_base.py +++ b/numpy/lib/tests/test_shape_base.py @@ -3,7 +3,7 @@ from __future__ import division, absolute_import, print_function import numpy as np from numpy.lib.shape_base import ( apply_along_axis, apply_over_axes, array_split, split, hsplit, dsplit, - vsplit, dstack, kron, tile + vsplit, dstack, column_stack, kron, tile ) from numpy.testing import ( run_module_suite, TestCase, assert_, assert_equal, assert_array_equal, @@ -27,6 +27,37 @@ class TestApplyAlongAxis(TestCase): assert_array_equal(apply_along_axis(np.sum, 0, a), [[27, 30, 33], [36, 39, 42], [45, 48, 51]]) + def test_preserve_subclass(self): + def double(row): + return row * 2 + m = np.matrix([[0, 1], [2, 3]]) + result = apply_along_axis(double, 0, m) + assert isinstance(result, np.matrix) + assert_array_equal( + result, np.matrix([[0, 2], [4, 6]]) + ) + + def test_subclass(self): + class MinimalSubclass(np.ndarray): + data = 1 + + def minimal_function(array): + return array.data + + a = np.zeros((6, 3)).view(MinimalSubclass) + + assert_array_equal( + apply_along_axis(minimal_function, 0, a), np.array([1, 1, 1]) + ) + + def test_scalar_array(self): + class MinimalSubclass(np.ndarray): + pass + a = np.ones((6, 3)).view(MinimalSubclass) + res = apply_along_axis(np.sum, 0, a) + assert isinstance(res, MinimalSubclass) + assert_array_equal(res, np.array([6, 6, 6]).view(MinimalSubclass)) + class TestApplyOverAxes(TestCase): def test_simple(self): @@ -103,12 +134,17 @@ class TestArraySplit(TestCase): def test_integer_split_2D_rows(self): a = np.array([np.arange(10), np.arange(10)]) - res = assert_warns(FutureWarning, array_split, a, 3, axis=0) + res = array_split(a, 3, axis=0) + tgt = [np.array([np.arange(10)]), np.array([np.arange(10)]), + np.zeros((0, 10))] + compare_results(res, tgt) + assert_(a.dtype.type is res[-1].dtype.type) - # After removing the FutureWarning, the last should be zeros((0, 10)) - desired = [np.array([np.arange(10)]), np.array([np.arange(10)]), - np.array([])] - compare_results(res, desired) + # Same thing for manual splits: + res = array_split(a, [0, 1, 2], axis=0) + tgt = [np.zeros((0, 10)), np.array([np.arange(10)]), + np.array([np.arange(10)])] + compare_results(res, tgt) assert_(a.dtype.type is res[-1].dtype.type) def test_integer_split_2D_cols(self): @@ -123,12 +159,10 @@ class TestArraySplit(TestCase): """ This will fail if we change default axis """ a = np.array([np.arange(10), np.arange(10)]) - res = assert_warns(FutureWarning, array_split, a, 3) - - # After removing the FutureWarning, the last should be zeros((0, 10)) - desired = [np.array([np.arange(10)]), np.array([np.arange(10)]), - np.array([])] - compare_results(res, desired) + res = array_split(a, 3) + tgt = [np.array([np.arange(10)]), np.array([np.arange(10)]), + np.zeros((0, 10))] + compare_results(res, tgt) assert_(a.dtype.type is res[-1].dtype.type) # perhaps should check higher dimensions @@ -172,8 +206,15 @@ class TestSplit(TestCase): a = np.arange(10) assert_raises(ValueError, split, a, 3) +class TestColumnStack(TestCase): + def test_non_iterable(self): + assert_raises(TypeError, column_stack, 1) + class TestDstack(TestCase): + def test_non_iterable(self): + assert_raises(TypeError, dstack, 1) + def test_0D_array(self): a = np.array(1) b = np.array(2) @@ -209,6 +250,9 @@ class TestHsplit(TestCase): """Only testing for integer splits. """ + def test_non_iterable(self): + assert_raises(ValueError, hsplit, 1, 1) + def test_0D_array(self): a = np.array(1) try: @@ -235,6 +279,13 @@ class TestVsplit(TestCase): """Only testing for integer splits. """ + def test_non_iterable(self): + assert_raises(ValueError, vsplit, 1, 1) + + def test_0D_array(self): + a = np.array(1) + assert_raises(ValueError, vsplit, a, 2) + def test_1D_array(self): a = np.array([1, 2, 3, 4]) try: @@ -253,6 +304,16 @@ class TestVsplit(TestCase): class TestDsplit(TestCase): # Only testing for integer splits. + def test_non_iterable(self): + assert_raises(ValueError, dsplit, 1, 1) + + def test_0D_array(self): + a = np.array(1) + assert_raises(ValueError, dsplit, a, 2) + + def test_1D_array(self): + a = np.array([1, 2, 3, 4]) + assert_raises(ValueError, dsplit, a, 2) def test_2D_array(self): a = np.array([[1, 2, 3, 4], @@ -324,9 +385,18 @@ class TestTile(TestCase): assert_equal(tile(b, (2, 2)), [[1, 2, 1, 2], [3, 4, 3, 4], [1, 2, 1, 2], [3, 4, 3, 4]]) + def test_tile_one_repetition_on_array_gh4679(self): + a = np.arange(5) + b = tile(a, 1) + b += 2 + assert_equal(a, np.arange(5)) + def test_empty(self): a = np.array([[[]]]) + b = np.array([[], []]) + c = tile(b, 2).shape d = tile(a, (3, 2, 5)).shape + assert_equal(c, (2, 0)) assert_equal(d, (3, 2, 0)) def test_kroncompare(self): diff --git a/numpy/lib/tests/test_stride_tricks.py b/numpy/lib/tests/test_stride_tricks.py index bc7e30ca4..95df135cf 100644 --- a/numpy/lib/tests/test_stride_tricks.py +++ b/numpy/lib/tests/test_stride_tricks.py @@ -5,8 +5,9 @@ from numpy.testing import ( run_module_suite, assert_equal, assert_array_equal, assert_raises, assert_ ) -from numpy.lib.stride_tricks import as_strided, broadcast_arrays - +from numpy.lib.stride_tricks import ( + as_strided, broadcast_arrays, _broadcast_shape, broadcast_to +) def assert_shapes_correct(input_shapes, expected_shape): # Broadcast a list of arrays with the given input shapes and check the @@ -217,6 +218,67 @@ def test_same_as_ufunc(): assert_same_as_ufunc(input_shapes[0], input_shapes[1], False, True) assert_same_as_ufunc(input_shapes[0], input_shapes[1], True, True) + +def test_broadcast_to_succeeds(): + data = [ + [np.array(0), (0,), np.array(0)], + [np.array(0), (1,), np.zeros(1)], + [np.array(0), (3,), np.zeros(3)], + [np.ones(1), (1,), np.ones(1)], + [np.ones(1), (2,), np.ones(2)], + [np.ones(1), (1, 2, 3), np.ones((1, 2, 3))], + [np.arange(3), (3,), np.arange(3)], + [np.arange(3), (1, 3), np.arange(3).reshape(1, -1)], + [np.arange(3), (2, 3), np.array([[0, 1, 2], [0, 1, 2]])], + # test if shape is not a tuple + [np.ones(0), 0, np.ones(0)], + [np.ones(1), 1, np.ones(1)], + [np.ones(1), 2, np.ones(2)], + # these cases with size 0 are strange, but they reproduce the behavior + # of broadcasting with ufuncs (see test_same_as_ufunc above) + [np.ones(1), (0,), np.ones(0)], + [np.ones((1, 2)), (0, 2), np.ones((0, 2))], + [np.ones((2, 1)), (2, 0), np.ones((2, 0))], + ] + for input_array, shape, expected in data: + actual = broadcast_to(input_array, shape) + assert_array_equal(expected, actual) + + +def test_broadcast_to_raises(): + data = [ + [(0,), ()], + [(1,), ()], + [(3,), ()], + [(3,), (1,)], + [(3,), (2,)], + [(3,), (4,)], + [(1, 2), (2, 1)], + [(1, 1), (1,)], + [(1,), -1], + [(1,), (-1,)], + [(1, 2), (-1, 2)], + ] + for orig_shape, target_shape in data: + arr = np.zeros(orig_shape) + assert_raises(ValueError, lambda: broadcast_to(arr, target_shape)) + + +def test_broadcast_shape(): + # broadcast_shape is already exercized indirectly by broadcast_arrays + assert_raises(ValueError, _broadcast_shape) + assert_equal(_broadcast_shape([1, 2]), (2,)) + assert_equal(_broadcast_shape(np.ones((1, 1))), (1, 1)) + assert_equal(_broadcast_shape(np.ones((1, 1)), np.ones((3, 4))), (3, 4)) + assert_equal(_broadcast_shape(*([np.ones((1, 2))] * 32)), (1, 2)) + assert_equal(_broadcast_shape(*([np.ones((1, 2))] * 100)), (1, 2)) + + # regression tests for gh-5862 + assert_equal(_broadcast_shape(*([np.ones(2)] * 32 + [1])), (2,)) + bad_args = [np.ones(2)] * 32 + [np.ones(3)] * 32 + assert_raises(ValueError, lambda: _broadcast_shape(*bad_args)) + + def test_as_strided(): a = np.array([None]) a_view = as_strided(a) @@ -233,6 +295,45 @@ def test_as_strided(): expected = np.array([[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]) assert_array_equal(a_view, expected) + # Regression test for gh-5081 + dt = np.dtype([('num', 'i4'), ('obj', 'O')]) + a = np.empty((4,), dtype=dt) + a['num'] = np.arange(1, 5) + a_view = as_strided(a, shape=(3, 4), strides=(0, a.itemsize)) + expected_num = [[1, 2, 3, 4]] * 3 + expected_obj = [[None]*4]*3 + assert_equal(a_view.dtype, dt) + assert_array_equal(expected_num, a_view['num']) + assert_array_equal(expected_obj, a_view['obj']) + + # Make sure that void types without fields are kept unchanged + a = np.empty((4,), dtype='V4') + a_view = as_strided(a, shape=(3, 4), strides=(0, a.itemsize)) + assert_equal(a.dtype, a_view.dtype) + + # Make sure that the only type that could fail is properly handled + dt = np.dtype({'names': [''], 'formats': ['V4']}) + a = np.empty((4,), dtype=dt) + a_view = as_strided(a, shape=(3, 4), strides=(0, a.itemsize)) + assert_equal(a.dtype, a_view.dtype) + +def as_strided_writeable(): + arr = np.ones(10) + view = as_strided(arr, writeable=False) + assert_(not view.flags.writeable) + + # Check that writeable also is fine: + view = as_strided(arr, writeable=True) + assert_(view.flags.writeable) + view[...] = 3 + assert_array_equal(arr, np.full_like(arr, 3)) + + # Test that things do not break down for readonly: + arr.flags.writeable = False + view = as_strided(arr, writeable=False) + view = as_strided(arr, writeable=True) + assert_(not view.flags.writeable) + class VerySimpleSubClass(np.ndarray): def __new__(cls, *args, **kwargs): @@ -277,6 +378,53 @@ def test_subclasses(): assert_(type(b_view) is np.ndarray) assert_(a_view.shape == b_view.shape) + # and for broadcast_to + shape = (2, 4) + a_view = broadcast_to(a, shape) + assert_(type(a_view) is np.ndarray) + assert_(a_view.shape == shape) + a_view = broadcast_to(a, shape, subok=True) + assert_(type(a_view) is SimpleSubClass) + assert_(a_view.info == 'simple finalized') + assert_(a_view.shape == shape) + + +def test_writeable(): + # broadcast_to should return a readonly array + original = np.array([1, 2, 3]) + result = broadcast_to(original, (2, 3)) + assert_equal(result.flags.writeable, False) + assert_raises(ValueError, result.__setitem__, slice(None), 0) + + # but the result of broadcast_arrays needs to be writeable (for now), to + # preserve backwards compatibility + for results in [broadcast_arrays(original), + broadcast_arrays(0, original)]: + for result in results: + assert_equal(result.flags.writeable, True) + # keep readonly input readonly + original.flags.writeable = False + _, result = broadcast_arrays(0, original) + assert_equal(result.flags.writeable, False) + + # regresssion test for GH6491 + shape = (2,) + strides = [0] + tricky_array = as_strided(np.array(0), shape, strides) + other = np.zeros((1,)) + first, second = broadcast_arrays(tricky_array, other) + assert_(first.shape == second.shape) + + +def test_reference_types(): + input_array = np.array('a', dtype=object) + expected = np.array(['a'] * 3, dtype=object) + actual = broadcast_to(input_array, (3,)) + assert_array_equal(expected, actual) + + actual, _ = broadcast_arrays(input_array, np.ones(3)) + assert_array_equal(expected, actual) + if __name__ == "__main__": run_module_suite() diff --git a/numpy/lib/tests/test_twodim_base.py b/numpy/lib/tests/test_twodim_base.py index 739061a5d..98b8aa39c 100644 --- a/numpy/lib/tests/test_twodim_base.py +++ b/numpy/lib/tests/test_twodim_base.py @@ -5,11 +5,11 @@ from __future__ import division, absolute_import, print_function from numpy.testing import ( TestCase, run_module_suite, assert_equal, assert_array_equal, - assert_array_max_ulp, assert_array_almost_equal, assert_raises, rand, + assert_array_max_ulp, assert_array_almost_equal, assert_raises, ) from numpy import ( - arange, rot90, add, fliplr, flipud, zeros, ones, eye, array, diag, + arange, add, fliplr, flipud, zeros, ones, eye, array, diag, histogram2d, tri, mask_indices, triu_indices, triu_indices_from, tril_indices, tril_indices_from, vander, ) @@ -169,37 +169,6 @@ class TestFlipud(TestCase): assert_equal(flipud(a), b) -class TestRot90(TestCase): - def test_basic(self): - self.assertRaises(ValueError, rot90, ones(4)) - - a = [[0, 1, 2], - [3, 4, 5]] - b1 = [[2, 5], - [1, 4], - [0, 3]] - b2 = [[5, 4, 3], - [2, 1, 0]] - b3 = [[3, 0], - [4, 1], - [5, 2]] - b4 = [[0, 1, 2], - [3, 4, 5]] - - for k in range(-3, 13, 4): - assert_equal(rot90(a, k=k), b1) - for k in range(-2, 13, 4): - assert_equal(rot90(a, k=k), b2) - for k in range(-1, 13, 4): - assert_equal(rot90(a, k=k), b3) - for k in range(0, 13, 4): - assert_equal(rot90(a, k=k), b4) - - def test_axes(self): - a = ones((50, 40, 3)) - assert_equal(rot90(a).shape, (40, 50, 3)) - - class TestHistogram2d(TestCase): def test_simple(self): x = array( @@ -254,7 +223,7 @@ class TestHistogram2d(TestCase): assert_array_almost_equal(H, answer, 3) def test_all_outliers(self): - r = rand(100) + 1. + 1e6 # histogramdd rounds by decimal=6 + r = np.random.rand(100) + 1. + 1e6 # histogramdd rounds by decimal=6 H, xed, yed = histogram2d(r, r, (4, 5), range=([0, 1], [0, 1])) assert_array_equal(H, 0) @@ -265,6 +234,37 @@ class TestHistogram2d(TestCase): a, edge1, edge2 = histogram2d([], [], bins=4) assert_array_max_ulp(a, np.zeros((4, 4))) + def test_binparameter_combination(self): + x = array( + [0, 0.09207008, 0.64575234, 0.12875982, 0.47390599, + 0.59944483, 1]) + y = array( + [0, 0.14344267, 0.48988575, 0.30558665, 0.44700682, + 0.15886423, 1]) + edges = (0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1) + H, xe, ye = histogram2d(x, y, (edges, 4)) + answer = array( + [[ 2., 0., 0., 0.], + [ 0., 1., 0., 0.], + [ 0., 0., 0., 0.], + [ 0., 0., 0., 0.], + [ 0., 1., 0., 0.], + [ 1., 0., 0., 0.], + [ 0., 1., 0., 0.], + [ 0., 0., 0., 0.], + [ 0., 0., 0., 0.], + [ 0., 0., 0., 1.]]) + assert_array_equal(H, answer) + assert_array_equal(ye, array([0., 0.25, 0.5, 0.75, 1])) + H, xe, ye = histogram2d(x, y, (4, edges)) + answer = array( + [[ 1., 1., 0., 1., 0., 0., 0., 0., 0., 0.], + [ 0., 0., 0., 0., 1., 0., 0., 0., 0., 0.], + [ 0., 1., 0., 0., 1., 0., 0., 0., 0., 0.], + [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 1.]]) + assert_array_equal(H, answer) + assert_array_equal(xe, array([0., 0.25, 0.5, 0.75, 1])) + class TestTri(TestCase): def test_dtype(self): diff --git a/numpy/lib/tests/test_type_check.py b/numpy/lib/tests/test_type_check.py index 3931f95e5..93a4da97a 100644 --- a/numpy/lib/tests/test_type_check.py +++ b/numpy/lib/tests/test_type_check.py @@ -18,11 +18,13 @@ def assert_all(x): class TestCommonType(TestCase): def test_basic(self): ai32 = np.array([[1, 2], [3, 4]], dtype=np.int32) + af16 = np.array([[1, 2], [3, 4]], dtype=np.float16) af32 = np.array([[1, 2], [3, 4]], dtype=np.float32) af64 = np.array([[1, 2], [3, 4]], dtype=np.float64) acs = np.array([[1+5j, 2+6j], [3+7j, 4+8j]], dtype=np.csingle) acd = np.array([[1+5j, 2+6j], [3+7j, 4+8j]], dtype=np.cdouble) assert_(common_type(ai32) == np.float64) + assert_(common_type(af16) == np.float16) assert_(common_type(af32) == np.float32) assert_(common_type(af64) == np.float64) assert_(common_type(acs) == np.csingle) @@ -146,6 +148,41 @@ class TestIscomplexobj(TestCase): z = np.array([-1j, 0, -1]) assert_(iscomplexobj(z)) + def test_scalar(self): + assert_(not iscomplexobj(1.0)) + assert_(iscomplexobj(1+0j)) + + def test_list(self): + assert_(iscomplexobj([3, 1+0j, True])) + assert_(not iscomplexobj([3, 1, True])) + + def test_duck(self): + class DummyComplexArray: + @property + def dtype(self): + return np.dtype(complex) + dummy = DummyComplexArray() + assert_(iscomplexobj(dummy)) + + def test_pandas_duck(self): + # This tests a custom np.dtype duck-typed class, such as used by pandas + # (pandas.core.dtypes) + class PdComplex(np.complex128): + pass + class PdDtype(object): + name = 'category' + names = None + type = PdComplex + kind = 'c' + str = '<c16' + base = np.dtype('complex128') + class DummyPd: + @property + def dtype(self): + return PdDtype + dummy = DummyPd() + assert_(iscomplexobj(dummy)) + class TestIsrealobj(TestCase): def test_basic(self): @@ -186,7 +223,7 @@ class TestIsnan(TestCase): class TestIsfinite(TestCase): - # Fixme, wrong place, isfinite now ufunc + # Fixme, wrong place, isfinite now ufunc def test_goodvalues(self): z = np.array((-1., 0., 1.)) @@ -217,7 +254,7 @@ class TestIsfinite(TestCase): class TestIsinf(TestCase): - # Fixme, wrong place, isinf now ufunc + # Fixme, wrong place, isinf now ufunc def test_goodvalues(self): z = np.array((-1., 0., 1.)) @@ -277,6 +314,8 @@ class TestNanToNum(TestCase): def test_integer(self): vals = nan_to_num(1) assert_all(vals == 1) + vals = nan_to_num([1]) + assert_array_equal(vals, np.array([1], np.int)) def test_complex_good(self): vals = nan_to_num(1+1j) diff --git a/numpy/lib/tests/test_utils.py b/numpy/lib/tests/test_utils.py index 8fbd1c445..92bcdc238 100644 --- a/numpy/lib/tests/test_utils.py +++ b/numpy/lib/tests/test_utils.py @@ -3,7 +3,7 @@ from __future__ import division, absolute_import, print_function import sys from numpy.core import arange from numpy.testing import ( - run_module_suite, assert_, assert_equal, dec + run_module_suite, assert_, assert_equal, assert_raises_regex, dec ) from numpy.lib import deprecate import numpy.lib.utils as utils @@ -62,5 +62,10 @@ def test_byte_bounds(): assert_equal(high - low, a.size * a.itemsize) +def test_assert_raises_regex_context_manager(): + with assert_raises_regex(ValueError, 'no deprecation warning'): + raise ValueError('no deprecation warning') + + if __name__ == "__main__": run_module_suite() |