diff options
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/lib/function_base.py | 30 | ||||
-rw-r--r-- | numpy/lib/tests/test_function_base.py | 25 |
2 files changed, 48 insertions, 7 deletions
diff --git a/numpy/lib/function_base.py b/numpy/lib/function_base.py index 7c5f0c5af..34c136064 100644 --- a/numpy/lib/function_base.py +++ b/numpy/lib/function_base.py @@ -158,8 +158,14 @@ def histogram(a, bins=10, range=None, normed=False, weights=None, density=None): 'max must be larger than min in range parameter.') if not iterable(bins): + if np.isscalar(bins) and bins < 1: + raise ValueError("`bins` should be a positive integer.") if range is None: - range = (a.min(), a.max()) + if a.size == 0: + # handle empty arrays. Can't determine range, so use 0-1. + range = (0, 1) + else: + range = (a.min(), a.max()) mn, mx = [mi+0.0 for mi in range] if mn == mx: mn -= 0.5 @@ -287,6 +293,7 @@ def histogramdd(sample, bins=10, range=None, normed=False, weights=None): 'The dimension of bins must be equal'\ ' to the dimension of the sample x.') except TypeError: + # bins is an integer bins = D*[bins] # Select range for each dimension @@ -314,12 +321,19 @@ def histogramdd(sample, bins=10, range=None, normed=False, weights=None): # Create edge arrays for i in arange(D): if isscalar(bins[i]): + if bins[i] < 1: + raise ValueError("Element at index %s in `bins` should be " + "a positive integer." % i) nbin[i] = bins[i] + 2 # +2 for outlier bins edges[i] = linspace(smin[i], smax[i], nbin[i]-1) else: edges[i] = asarray(bins[i], float) nbin[i] = len(edges[i])+1 # +1 for outlier bins dedges[i] = diff(edges[i]) + if np.any(np.asarray(dedges[i]) <= 0): + raise ValueError(""" + Found bin edge of size <= 0. Did you specify `bins` with + non-monotonic sequence?""") # Handle empty input. if N == 0: @@ -338,12 +352,14 @@ def histogramdd(sample, bins=10, range=None, normed=False, weights=None): outliers = zeros(N, int) for i in arange(D): # Rounding precision - decimal = int(-log10(dedges[i].min())) +6 - # Find which points are on the rightmost edge. - on_edge = where(around(sample[:,i], decimal) == around(edges[i][-1], - decimal))[0] - # Shift these points one bin to the left. - Ncount[i][on_edge] -= 1 + mindiff = dedges[i].min() + if not np.isinf(mindiff): + decimal = int(-log10(mindiff)) + 6 + # Find which points are on the rightmost edge. + on_edge = where(around(sample[:,i], decimal) == around(edges[i][-1], + decimal))[0] + # Shift these points one bin to the left. + Ncount[i][on_edge] -= 1 # Flattened histogram matrix (1D) # Reshape is used so that overlarge arrays diff --git a/numpy/lib/tests/test_function_base.py b/numpy/lib/tests/test_function_base.py index ea3ca4000..353bf23e9 100644 --- a/numpy/lib/tests/test_function_base.py +++ b/numpy/lib/tests/test_function_base.py @@ -556,6 +556,10 @@ class TestHistogram(TestCase): hist, edges = histogram([1, 2, 3, 4], [1, 2]) assert_array_equal(hist, [2, ]) assert_array_equal(edges, [1, 2]) + assert_raises(ValueError, histogram, [1, 2], bins=0) + h, e = histogram([1,2], bins=1) + assert_equal(h, array([2])) + assert_allclose(e, array([1., 2.])) def test_normed(self): # Check that the integral of the density equals 1. @@ -747,6 +751,27 @@ class TestHistogramdd(TestCase): a, b = histogramdd([[], []], bins=([0,1], [0,1])) assert_array_max_ulp(a, array([ 0., 0.])) + def test_bins_errors(self): + """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]) + assert_raises(ValueError, np.histogramdd, x, bins=[1, 1, 1, [1, 2, 2, 3]]) + assert_raises(ValueError, np.histogramdd, x, bins=[1, 1, 1, [1, 2, 3, -3]]) + 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.""" + x = np.arange(6).reshape(3, 2) + expected = np.array([[1, 0], [0, 1], [0, 1]]) + h, e = np.histogramdd(x, bins=[3, [-np.inf, 2, 10]]) + assert_allclose(h, expected) + h, e = np.histogramdd(x, bins=[3, np.array([-1, 2, np.inf])]) + assert_allclose(h, expected) + h, e = np.histogramdd(x, bins=[3, [-np.inf, 3, np.inf]]) + assert_allclose(h, expected) + class TestUnique(TestCase): def test_simple(self): |