summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/release/1.15.0-notes.rst6
-rw-r--r--numpy/core/_add_newdocs.py93
-rw-r--r--numpy/core/fromnumeric.py10
-rw-r--r--numpy/core/src/multiarray/compiled_base.c121
-rw-r--r--numpy/core/src/multiarray/compiled_base.h2
-rw-r--r--numpy/core/src/multiarray/mapping.c2
-rw-r--r--numpy/core/src/multiarray/multiarraymodule.c2
-rw-r--r--numpy/core/tests/test_regression.py12
-rw-r--r--numpy/lib/function_base.py112
-rw-r--r--numpy/lib/histograms.py26
-rw-r--r--numpy/lib/tests/test_function_base.py12
-rw-r--r--numpy/lib/tests/test_histograms.py16
-rw-r--r--numpy/lib/tests/test_twodim_base.py6
-rw-r--r--numpy/lib/twodim_base.py14
-rw-r--r--numpy/polynomial/chebyshev.py4
-rw-r--r--numpy/random/mtrand/randomkit.c2
-rwxr-xr-xtools/cythonize.py36
17 files changed, 245 insertions, 231 deletions
diff --git a/doc/release/1.15.0-notes.rst b/doc/release/1.15.0-notes.rst
index 8961de300..728465f1e 100644
--- a/doc/release/1.15.0-notes.rst
+++ b/doc/release/1.15.0-notes.rst
@@ -277,6 +277,12 @@ The ``range`` argument of `histogramdd` can now contain ``None`` values to
indicate that the range for the corresponding axis should be computed from the
data. Previously, this could not be specified on a per-axis basis.
+The normed arguments of ``histogramdd`` and ``histogram2d`` have been renamed
+-----------------------------------------------------------------------------
+These arguments are now called ``density``, which is consistent with
+``histogram``. The old argument continues to work, but the new name should be
+preferred.
+
``np.r_`` works with 0d arrays, and ``np.ma.mr_`` works with ``np.ma.masked``
----------------------------------------------------------------------------
0d arrays passed to the `r_` and `mr_` concatenation helpers are now treated as
diff --git a/numpy/core/_add_newdocs.py b/numpy/core/_add_newdocs.py
index f596e613f..d88667476 100644
--- a/numpy/core/_add_newdocs.py
+++ b/numpy/core/_add_newdocs.py
@@ -5296,99 +5296,6 @@ add_newdoc('numpy.core.umath', 'seterrobj',
#
##############################################################################
-add_newdoc('numpy.core.multiarray', 'digitize',
- """
- digitize(x, bins, right=False)
-
- Return the indices of the bins to which each value in input array belongs.
-
- ========= ============= ============================
- `right` order of bins returned index `i` satisfies
- ========= ============= ============================
- ``False`` increasing ``bins[i-1] <= x < bins[i]``
- ``True`` increasing ``bins[i-1] < x <= bins[i]``
- ``False`` decreasing ``bins[i-1] > x >= bins[i]``
- ``True`` decreasing ``bins[i-1] >= x > bins[i]``
- ========= ============= ============================
-
- If values in `x` are beyond the bounds of `bins`, 0 or ``len(bins)`` is
- returned as appropriate.
-
- Parameters
- ----------
- x : array_like
- Input array to be binned. Prior to NumPy 1.10.0, this array had to
- be 1-dimensional, but can now have any shape.
- bins : array_like
- Array of bins. It has to be 1-dimensional and monotonic.
- right : bool, optional
- Indicating whether the intervals include the right or the left bin
- edge. Default behavior is (right==False) indicating that the interval
- does not include the right edge. The left bin end is open in this
- case, i.e., bins[i-1] <= x < bins[i] is the default behavior for
- monotonically increasing bins.
-
- Returns
- -------
- indices : ndarray of ints
- Output array of indices, of same shape as `x`.
-
- Raises
- ------
- ValueError
- If `bins` is not monotonic.
- TypeError
- If the type of the input is complex.
-
- See Also
- --------
- bincount, histogram, unique, searchsorted
-
- Notes
- -----
- If values in `x` are such that they fall outside the bin range,
- attempting to index `bins` with the indices that `digitize` returns
- will result in an IndexError.
-
- .. versionadded:: 1.10.0
-
- `np.digitize` is implemented in terms of `np.searchsorted`. This means
- that a binary search is used to bin the values, which scales much better
- for larger number of bins than the previous linear search. It also removes
- the requirement for the input array to be 1-dimensional.
-
- For monotonically _increasing_ `bins`, the following are equivalent::
-
- np.digitize(x, bins, right=True)
- np.searchsorted(bins, x, side='left')
-
- Note that as the order of the arguments are reversed, the side must be too.
- The `searchsorted` call is marginally faster, as it does not do any
- monotonicity checks. Perhaps more importantly, it supports all dtypes.
-
- Examples
- --------
- >>> x = np.array([0.2, 6.4, 3.0, 1.6])
- >>> bins = np.array([0.0, 1.0, 2.5, 4.0, 10.0])
- >>> inds = np.digitize(x, bins)
- >>> inds
- array([1, 4, 3, 2])
- >>> for n in range(x.size):
- ... print(bins[inds[n]-1], "<=", x[n], "<", bins[inds[n]])
- ...
- 0.0 <= 0.2 < 1.0
- 4.0 <= 6.4 < 10.0
- 2.5 <= 3.0 < 4.0
- 1.0 <= 1.6 < 2.5
-
- >>> x = np.array([1.2, 10.0, 12.4, 15.5, 20.])
- >>> bins = np.array([0, 5, 10, 15, 20])
- >>> np.digitize(x,bins,right=True)
- array([1, 2, 3, 4, 4])
- >>> np.digitize(x,bins,right=False)
- array([1, 3, 3, 4, 5])
- """)
-
add_newdoc('numpy.core.multiarray', 'bincount',
"""
bincount(x, weights=None, minlength=0)
diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py
index 373e0fde8..b9cc98cae 100644
--- a/numpy/core/fromnumeric.py
+++ b/numpy/core/fromnumeric.py
@@ -1198,6 +1198,16 @@ def resize(a, new_shape):
--------
ndarray.resize : resize an array in-place.
+ Notes
+ -----
+ Warning: This functionality does **not** consider axes separately,
+ i.e. it does not apply interpolation/extrapolation.
+ It fills the return array with the required number of elements, taken
+ from `a` as they are laid out in memory, disregarding strides and axes.
+ (This is in case the new shape is smaller. For larger, see above.)
+ This functionality is therefore not suitable to resize images,
+ or data where each axis represents a separate and distinct entity.
+
Examples
--------
>>> a=np.array([[0,1],[2,3]])
diff --git a/numpy/core/src/multiarray/compiled_base.c b/numpy/core/src/multiarray/compiled_base.c
index 8c140f5e2..1c27f8394 100644
--- a/numpy/core/src/multiarray/compiled_base.c
+++ b/numpy/core/src/multiarray/compiled_base.c
@@ -21,11 +21,17 @@
* and 0 if the array is not monotonic.
*/
static int
-check_array_monotonic(const double *a, npy_int lena)
+check_array_monotonic(const double *a, npy_intp lena)
{
npy_intp i;
double next;
- double last = a[0];
+ double last;
+
+ if (lena == 0) {
+ /* all bin edges hold the same value */
+ return 1;
+ }
+ last = a[0];
/* Skip repeated values at the beginning of the array */
for (i = 1; (i < lena) && (a[i] == last); i++);
@@ -209,106 +215,41 @@ fail:
return NULL;
}
-/*
- * digitize(x, bins, right=False) returns an array of integers the same length
- * as x. The values i returned are such that bins[i - 1] <= x < bins[i] if
- * bins is monotonically increasing, or bins[i - 1] > x >= bins[i] if bins
- * is monotonically decreasing. Beyond the bounds of bins, returns either
- * i = 0 or i = len(bins) as appropriate. If right == True the comparison
- * is bins [i - 1] < x <= bins[i] or bins [i - 1] >= x > bins[i]
- */
+/* Internal function to expose check_array_monotonic to python */
NPY_NO_EXPORT PyObject *
-arr_digitize(PyObject *NPY_UNUSED(self), PyObject *args, PyObject *kwds)
+arr__monotonicity(PyObject *NPY_UNUSED(self), PyObject *args, PyObject *kwds)
{
+ static char *kwlist[] = {"x", NULL};
PyObject *obj_x = NULL;
- PyObject *obj_bins = NULL;
PyArrayObject *arr_x = NULL;
- PyArrayObject *arr_bins = NULL;
- PyObject *ret = NULL;
- npy_intp len_bins;
- int monotonic, right = 0;
- NPY_BEGIN_THREADS_DEF
-
- static char *kwlist[] = {"x", "bins", "right", NULL};
+ long monotonic;
+ npy_intp len_x;
+ NPY_BEGIN_THREADS_DEF;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|i:digitize", kwlist,
- &obj_x, &obj_bins, &right)) {
- goto fail;
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|_monotonicity", kwlist,
+ &obj_x)) {
+ return NULL;
}
- /* PyArray_SearchSorted will make `x` contiguous even if we don't */
- arr_x = (PyArrayObject *)PyArray_FROMANY(obj_x, NPY_DOUBLE, 0, 0,
- NPY_ARRAY_CARRAY_RO);
+ /*
+ * TODO:
+ * `x` could be strided, needs change to check_array_monotonic
+ * `x` is forced to double for this check
+ */
+ arr_x = (PyArrayObject *)PyArray_FROMANY(
+ obj_x, NPY_DOUBLE, 1, 1, NPY_ARRAY_CARRAY_RO);
if (arr_x == NULL) {
- goto fail;
- }
-
- /* TODO: `bins` could be strided, needs change to check_array_monotonic */
- arr_bins = (PyArrayObject *)PyArray_FROMANY(obj_bins, NPY_DOUBLE, 1, 1,
- NPY_ARRAY_CARRAY_RO);
- if (arr_bins == NULL) {
- goto fail;
- }
-
- len_bins = PyArray_SIZE(arr_bins);
- if (len_bins == 0) {
- PyErr_SetString(PyExc_ValueError, "bins must have non-zero length");
- goto fail;
+ return NULL;
}
- NPY_BEGIN_THREADS_THRESHOLDED(len_bins)
- monotonic = check_array_monotonic((const double *)PyArray_DATA(arr_bins),
- len_bins);
+ len_x = PyArray_SIZE(arr_x);
+ NPY_BEGIN_THREADS_THRESHOLDED(len_x)
+ monotonic = check_array_monotonic(
+ (const double *)PyArray_DATA(arr_x), len_x);
NPY_END_THREADS
+ Py_DECREF(arr_x);
- if (monotonic == 0) {
- PyErr_SetString(PyExc_ValueError,
- "bins must be monotonically increasing or decreasing");
- goto fail;
- }
-
- /* PyArray_SearchSorted needs an increasing array */
- if (monotonic == - 1) {
- PyArrayObject *arr_tmp = NULL;
- npy_intp shape = PyArray_DIM(arr_bins, 0);
- npy_intp stride = -PyArray_STRIDE(arr_bins, 0);
- void *data = (void *)(PyArray_BYTES(arr_bins) - stride * (shape - 1));
-
- arr_tmp = (PyArrayObject *)PyArray_NewFromDescrAndBase(
- &PyArray_Type, PyArray_DescrFromType(NPY_DOUBLE),
- 1, &shape, &stride, data,
- PyArray_FLAGS(arr_bins), NULL, (PyObject *)arr_bins);
- Py_DECREF(arr_bins);
- if (!arr_tmp) {
- goto fail;
- }
- arr_bins = arr_tmp;
- }
-
- ret = PyArray_SearchSorted(arr_bins, (PyObject *)arr_x,
- right ? NPY_SEARCHLEFT : NPY_SEARCHRIGHT, NULL);
- if (!ret) {
- goto fail;
- }
-
- /* If bins is decreasing, ret has bins from end, not start */
- if (monotonic == -1) {
- npy_intp *ret_data =
- (npy_intp *)PyArray_DATA((PyArrayObject *)ret);
- npy_intp len_ret = PyArray_SIZE((PyArrayObject *)ret);
-
- NPY_BEGIN_THREADS_THRESHOLDED(len_ret)
- while (len_ret--) {
- *ret_data = len_bins - *ret_data;
- ret_data++;
- }
- NPY_END_THREADS
- }
-
- fail:
- Py_XDECREF(arr_x);
- Py_XDECREF(arr_bins);
- return ret;
+ return PyInt_FromLong(monotonic);
}
/*
diff --git a/numpy/core/src/multiarray/compiled_base.h b/numpy/core/src/multiarray/compiled_base.h
index 51508531c..082139910 100644
--- a/numpy/core/src/multiarray/compiled_base.h
+++ b/numpy/core/src/multiarray/compiled_base.h
@@ -7,7 +7,7 @@ arr_insert(PyObject *, PyObject *, PyObject *);
NPY_NO_EXPORT PyObject *
arr_bincount(PyObject *, PyObject *, PyObject *);
NPY_NO_EXPORT PyObject *
-arr_digitize(PyObject *, PyObject *, PyObject *kwds);
+arr__monotonicity(PyObject *, PyObject *, PyObject *kwds);
NPY_NO_EXPORT PyObject *
arr_interp(PyObject *, PyObject *, PyObject *);
NPY_NO_EXPORT PyObject *
diff --git a/numpy/core/src/multiarray/mapping.c b/numpy/core/src/multiarray/mapping.c
index cdca1d606..f338226c2 100644
--- a/numpy/core/src/multiarray/mapping.c
+++ b/numpy/core/src/multiarray/mapping.c
@@ -1540,13 +1540,11 @@ _get_field_view(PyArrayObject *arr, PyObject *ind, PyArrayObject **view,
"cannot use field titles in multi-field index");
}
if (titlecmp != 0 || PyDict_SetItem(fields, title, tup) < 0) {
- Py_DECREF(title);
Py_DECREF(name);
Py_DECREF(fields);
Py_DECREF(names);
return 0;
}
- Py_DECREF(title);
}
/* disallow duplicate field indices */
if (PyDict_Contains(fields, name)) {
diff --git a/numpy/core/src/multiarray/multiarraymodule.c b/numpy/core/src/multiarray/multiarraymodule.c
index e6af5a81e..6e57f1d6d 100644
--- a/numpy/core/src/multiarray/multiarraymodule.c
+++ b/numpy/core/src/multiarray/multiarraymodule.c
@@ -4345,7 +4345,7 @@ static struct PyMethodDef array_module_methods[] = {
"indicated by mask."},
{"bincount", (PyCFunction)arr_bincount,
METH_VARARGS | METH_KEYWORDS, NULL},
- {"digitize", (PyCFunction)arr_digitize,
+ {"_monotonicity", (PyCFunction)arr__monotonicity,
METH_VARARGS | METH_KEYWORDS, NULL},
{"interp", (PyCFunction)arr_interp,
METH_VARARGS | METH_KEYWORDS, NULL},
diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py
index ba4413138..62f592524 100644
--- a/numpy/core/tests/test_regression.py
+++ b/numpy/core/tests/test_regression.py
@@ -2391,3 +2391,15 @@ class TestRegression(object):
squeezed = scvalue.squeeze(axis=axis)
assert_equal(squeezed, scvalue)
assert_equal(type(squeezed), type(scvalue))
+
+ def test_field_access_by_title(self):
+ # gh-11507
+ s = 'Some long field name'
+ if HAS_REFCOUNT:
+ base = sys.getrefcount(s)
+ t = np.dtype([((s, 'f1'), np.float64)])
+ data = np.zeros(10, t)
+ for i in range(10):
+ v = str(data[['f1']])
+ if HAS_REFCOUNT:
+ assert_(base <= sys.getrefcount(s))
diff --git a/numpy/lib/function_base.py b/numpy/lib/function_base.py
index 9a680dd55..1a43da8b0 100644
--- a/numpy/lib/function_base.py
+++ b/numpy/lib/function_base.py
@@ -31,7 +31,7 @@ from numpy.core.function_base import add_newdoc
from numpy.lib.twodim_base import diag
from .utils import deprecate
from numpy.core.multiarray import (
- _insert, add_docstring, digitize, bincount, normalize_axis_index,
+ _insert, add_docstring, bincount, normalize_axis_index, _monotonicity,
interp as compiled_interp, interp_complex as compiled_interp_complex
)
from numpy.core.umath import _add_newdoc_ufunc as add_newdoc_ufunc
@@ -4493,3 +4493,113 @@ def append(arr, values, axis=None):
values = ravel(values)
axis = arr.ndim-1
return concatenate((arr, values), axis=axis)
+
+
+def digitize(x, bins, right=False):
+ """
+ Return the indices of the bins to which each value in input array belongs.
+
+ ========= ============= ============================
+ `right` order of bins returned index `i` satisfies
+ ========= ============= ============================
+ ``False`` increasing ``bins[i-1] <= x < bins[i]``
+ ``True`` increasing ``bins[i-1] < x <= bins[i]``
+ ``False`` decreasing ``bins[i-1] > x >= bins[i]``
+ ``True`` decreasing ``bins[i-1] >= x > bins[i]``
+ ========= ============= ============================
+
+ If values in `x` are beyond the bounds of `bins`, 0 or ``len(bins)`` is
+ returned as appropriate.
+
+ Parameters
+ ----------
+ x : array_like
+ Input array to be binned. Prior to NumPy 1.10.0, this array had to
+ be 1-dimensional, but can now have any shape.
+ bins : array_like
+ Array of bins. It has to be 1-dimensional and monotonic.
+ right : bool, optional
+ Indicating whether the intervals include the right or the left bin
+ edge. Default behavior is (right==False) indicating that the interval
+ does not include the right edge. The left bin end is open in this
+ case, i.e., bins[i-1] <= x < bins[i] is the default behavior for
+ monotonically increasing bins.
+
+ Returns
+ -------
+ indices : ndarray of ints
+ Output array of indices, of same shape as `x`.
+
+ Raises
+ ------
+ ValueError
+ If `bins` is not monotonic.
+ TypeError
+ If the type of the input is complex.
+
+ See Also
+ --------
+ bincount, histogram, unique, searchsorted
+
+ Notes
+ -----
+ If values in `x` are such that they fall outside the bin range,
+ attempting to index `bins` with the indices that `digitize` returns
+ will result in an IndexError.
+
+ .. versionadded:: 1.10.0
+
+ `np.digitize` is implemented in terms of `np.searchsorted`. This means
+ that a binary search is used to bin the values, which scales much better
+ for larger number of bins than the previous linear search. It also removes
+ the requirement for the input array to be 1-dimensional.
+
+ For monotonically _increasing_ `bins`, the following are equivalent::
+
+ np.digitize(x, bins, right=True)
+ np.searchsorted(bins, x, side='left')
+
+ Note that as the order of the arguments are reversed, the side must be too.
+ The `searchsorted` call is marginally faster, as it does not do any
+ monotonicity checks. Perhaps more importantly, it supports all dtypes.
+
+ Examples
+ --------
+ >>> x = np.array([0.2, 6.4, 3.0, 1.6])
+ >>> bins = np.array([0.0, 1.0, 2.5, 4.0, 10.0])
+ >>> inds = np.digitize(x, bins)
+ >>> inds
+ array([1, 4, 3, 2])
+ >>> for n in range(x.size):
+ ... print(bins[inds[n]-1], "<=", x[n], "<", bins[inds[n]])
+ ...
+ 0.0 <= 0.2 < 1.0
+ 4.0 <= 6.4 < 10.0
+ 2.5 <= 3.0 < 4.0
+ 1.0 <= 1.6 < 2.5
+
+ >>> x = np.array([1.2, 10.0, 12.4, 15.5, 20.])
+ >>> bins = np.array([0, 5, 10, 15, 20])
+ >>> np.digitize(x,bins,right=True)
+ array([1, 2, 3, 4, 4])
+ >>> np.digitize(x,bins,right=False)
+ array([1, 3, 3, 4, 5])
+ """
+ x = _nx.asarray(x)
+ bins = _nx.asarray(bins)
+
+ # here for compatibility, searchsorted below is happy to take this
+ if np.issubdtype(x.dtype, _nx.complexfloating):
+ raise TypeError("x may not be complex")
+
+ mono = _monotonicity(bins)
+ if mono == 0:
+ raise ValueError("bins must be monotonically increasing or decreasing")
+
+ # this is backwards because the arguments below are swapped
+ side = 'left' if right else 'right'
+ if mono == -1:
+ # reverse the bins, and invert the results
+ return len(bins) - _nx.searchsorted(bins[::-1], x, side=side)
+ else:
+ return _nx.searchsorted(bins, x, side=side)
diff --git a/numpy/lib/histograms.py b/numpy/lib/histograms.py
index ad7215504..422b356f7 100644
--- a/numpy/lib/histograms.py
+++ b/numpy/lib/histograms.py
@@ -812,7 +812,8 @@ def histogram(a, bins=10, range=None, normed=None, weights=None,
return n, bin_edges
-def histogramdd(sample, bins=10, range=None, normed=False, weights=None):
+def histogramdd(sample, bins=10, range=None, normed=None, weights=None,
+ density=None):
"""
Compute the multidimensional histogram of some data.
@@ -845,9 +846,14 @@ def histogramdd(sample, bins=10, range=None, normed=False, weights=None):
An entry of None in the sequence results in the minimum and maximum
values being used for the corresponding dimension.
The default, None, is equivalent to passing a tuple of D None values.
+ density : bool, optional
+ If False, the default, returns the number of samples in each bin.
+ If True, returns the probability *density* function at the bin,
+ ``bin_count / sample_count / bin_volume``.
normed : bool, optional
- If False, returns the number of samples in each bin. If True,
- returns the bin density ``bin_count / sample_count / bin_volume``.
+ An alias for the density argument that behaves identically. To avoid
+ confusion with the broken normed argument to `histogram`, `density`
+ should be preferred.
weights : (N,) array_like, optional
An array of values `w_i` weighing each sample `(x_i, y_i, z_i, ...)`.
Weights are normalized to 1 if normed is True. If normed is False,
@@ -961,8 +967,18 @@ def histogramdd(sample, bins=10, range=None, normed=False, weights=None):
core = D*(slice(1, -1),)
hist = hist[core]
- # Normalize if normed is True
- if normed:
+ # handle the aliasing normed argument
+ if normed is None:
+ if density is None:
+ density = False
+ elif density is None:
+ # an explicit normed argument was passed, alias it to the new name
+ density = normed
+ else:
+ raise TypeError("Cannot specify both 'normed' and 'density'")
+
+ if density:
+ # calculate the probability density function
s = hist.sum()
for i in _range(D):
shape = np.ones(D, int)
diff --git a/numpy/lib/tests/test_function_base.py b/numpy/lib/tests/test_function_base.py
index d2a9181db..ba5b90e8c 100644
--- a/numpy/lib/tests/test_function_base.py
+++ b/numpy/lib/tests/test_function_base.py
@@ -1510,6 +1510,18 @@ class TestDigitize(object):
assert_(not isinstance(digitize(b, a, False), A))
assert_(not isinstance(digitize(b, a, True), A))
+ def test_large_integers_increasing(self):
+ # gh-11022
+ x = 2**54 # loses precision in a float
+ assert_equal(np.digitize(x, [x - 1, x + 1]), 1)
+
+ @pytest.mark.xfail(
+ reason="gh-11022: np.core.multiarray._monoticity loses precision")
+ def test_large_integers_decreasing(self):
+ # gh-11022
+ x = 2**54 # loses precision in a float
+ assert_equal(np.digitize(x, [x + 1, x - 1]), 1)
+
class TestUnwrap(object):
diff --git a/numpy/lib/tests/test_histograms.py b/numpy/lib/tests/test_histograms.py
index d22aa5a27..f136b5c81 100644
--- a/numpy/lib/tests/test_histograms.py
+++ b/numpy/lib/tests/test_histograms.py
@@ -547,13 +547,13 @@ class TestHistogramdd(object):
# Check normalization
ed = [[-2, 0, 2], [0, 1, 2, 3], [0, 1, 2, 3]]
- H, edges = histogramdd(x, bins=ed, normed=True)
+ H, edges = histogramdd(x, bins=ed, density=True)
assert_(np.all(H == answer / 12.))
# Check that H has the correct shape.
H, edges = histogramdd(x, (2, 3, 4),
range=[[-1, 1], [0, 3], [0, 4]],
- normed=True)
+ density=True)
answer = np.array([[[0, 1, 0, 0], [0, 0, 1, 0], [1, 0, 0, 0]],
[[0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 1, 0]]])
assert_array_almost_equal(H, answer / 6., 4)
@@ -599,10 +599,10 @@ class TestHistogramdd(object):
def test_weights(self):
v = np.random.rand(100, 2)
hist, edges = histogramdd(v)
- n_hist, edges = histogramdd(v, normed=True)
+ n_hist, edges = histogramdd(v, density=True)
w_hist, edges = histogramdd(v, weights=np.ones(100))
assert_array_equal(w_hist, hist)
- w_hist, edges = histogramdd(v, weights=np.ones(100) * 2, normed=True)
+ w_hist, edges = histogramdd(v, weights=np.ones(100) * 2, density=True)
assert_array_equal(w_hist, n_hist)
w_hist, edges = histogramdd(v, weights=np.ones(100, int) * 2)
assert_array_equal(w_hist, 2 * hist)
@@ -708,7 +708,7 @@ class TestHistogramdd(object):
assert_equal(hist[0, 0], 1)
- def test_normed_non_uniform_2d(self):
+ def test_density_non_uniform_2d(self):
# Defines the following grid:
#
# 0 2 8
@@ -732,14 +732,14 @@ class TestHistogramdd(object):
assert_equal(hist, relative_areas)
# resulting histogram should be uniform, since counts and areas are propotional
- hist, edges = histogramdd((y, x), bins=(y_edges, x_edges), normed=True)
+ hist, edges = histogramdd((y, x), bins=(y_edges, x_edges), density=True)
assert_equal(hist, 1 / (8*8))
- def test_normed_non_uniform_1d(self):
+ def test_density_non_uniform_1d(self):
# compare to histogram to show the results are the same
v = np.arange(10)
bins = np.array([0, 1, 3, 6, 10])
hist, edges = histogram(v, bins, density=True)
- hist_dd, edges_dd = histogramdd((v,), (bins,), normed=True)
+ hist_dd, edges_dd = histogramdd((v,), (bins,), density=True)
assert_equal(hist, hist_dd)
assert_equal(edges, edges_dd[0])
diff --git a/numpy/lib/tests/test_twodim_base.py b/numpy/lib/tests/test_twodim_base.py
index d3a072af3..bf93b4adb 100644
--- a/numpy/lib/tests/test_twodim_base.py
+++ b/numpy/lib/tests/test_twodim_base.py
@@ -208,7 +208,7 @@ class TestHistogram2d(object):
x = array([1, 1, 2, 3, 4, 4, 4, 5])
y = array([1, 3, 2, 0, 1, 2, 3, 4])
H, xed, yed = histogram2d(
- x, y, (6, 5), range=[[0, 6], [0, 5]], normed=True)
+ x, y, (6, 5), range=[[0, 6], [0, 5]], density=True)
answer = array(
[[0., 0, 0, 0, 0],
[0, 1, 0, 1, 0],
@@ -220,11 +220,11 @@ class TestHistogram2d(object):
assert_array_equal(xed, np.linspace(0, 6, 7))
assert_array_equal(yed, np.linspace(0, 5, 6))
- def test_norm(self):
+ def test_density(self):
x = array([1, 2, 3, 1, 2, 3, 1, 2, 3])
y = array([1, 1, 1, 2, 2, 2, 3, 3, 3])
H, xed, yed = histogram2d(
- x, y, [[1, 2, 3, 5], [1, 2, 3, 5]], normed=True)
+ x, y, [[1, 2, 3, 5], [1, 2, 3, 5]], density=True)
answer = array([[1, 1, .5],
[1, 1, .5],
[.5, .5, .25]])/9.
diff --git a/numpy/lib/twodim_base.py b/numpy/lib/twodim_base.py
index cca316e9a..98efba191 100644
--- a/numpy/lib/twodim_base.py
+++ b/numpy/lib/twodim_base.py
@@ -530,7 +530,8 @@ def vander(x, N=None, increasing=False):
return v
-def histogram2d(x, y, bins=10, range=None, normed=False, weights=None):
+def histogram2d(x, y, bins=10, range=None, normed=None, weights=None,
+ density=None):
"""
Compute the bi-dimensional histogram of two data samples.
@@ -560,9 +561,14 @@ def histogram2d(x, y, bins=10, range=None, normed=False, weights=None):
(if not specified explicitly in the `bins` parameters):
``[[xmin, xmax], [ymin, ymax]]``. All values outside of this range
will be considered outliers and not tallied in the histogram.
+ density : bool, optional
+ If False, the default, returns the number of samples in each bin.
+ If True, returns the probability *density* function at the bin,
+ ``bin_count / sample_count / bin_area``.
normed : bool, optional
- If False, returns the number of samples in each bin. If True,
- returns the bin density ``bin_count / sample_count / bin_area``.
+ An alias for the density argument that behaves identically. To avoid
+ confusion with the broken normed argument to `histogram`, `density`
+ should be preferred.
weights : array_like, shape(N,), optional
An array of values ``w_i`` weighing each sample ``(x_i, y_i)``.
Weights are normalized to 1 if `normed` is True. If `normed` is
@@ -652,7 +658,7 @@ def histogram2d(x, y, bins=10, range=None, normed=False, weights=None):
if N != 1 and N != 2:
xedges = yedges = asarray(bins)
bins = [xedges, yedges]
- hist, edges = histogramdd([x, y], bins, range, normed, weights)
+ hist, edges = histogramdd([x, y], bins, range, normed, weights, density)
return hist, edges[0], edges[1]
diff --git a/numpy/polynomial/chebyshev.py b/numpy/polynomial/chebyshev.py
index 946e0499c..310c711ef 100644
--- a/numpy/polynomial/chebyshev.py
+++ b/numpy/polynomial/chebyshev.py
@@ -365,7 +365,7 @@ def poly2cheb(pol):
>>> c = p.convert(kind=P.Chebyshev)
>>> c
Chebyshev([ 1. , 3.25, 1. , 0.75], domain=[-1, 1], window=[-1, 1])
- >>> P.poly2cheb(range(4))
+ >>> P.chebyshev.poly2cheb(range(4))
array([ 1. , 3.25, 1. , 0.75])
"""
@@ -417,7 +417,7 @@ def cheb2poly(c):
>>> p = c.convert(kind=P.Polynomial)
>>> p
Polynomial([ -2., -8., 4., 12.], [-1., 1.])
- >>> P.cheb2poly(range(4))
+ >>> P.chebyshev.cheb2poly(range(4))
array([ -2., -8., 4., 12.])
"""
diff --git a/numpy/random/mtrand/randomkit.c b/numpy/random/mtrand/randomkit.c
index 380917180..6371ebe33 100644
--- a/numpy/random/mtrand/randomkit.c
+++ b/numpy/random/mtrand/randomkit.c
@@ -616,7 +616,7 @@ rk_gauss(rk_state *state)
}
while (r2 >= 1.0 || r2 == 0.0);
- /* Box-Muller transform */
+ /* Polar method, a more efficient version of the Box-Muller approach. */
f = sqrt(-2.0*log(r2)/r2);
/* Keep for next call */
state->gauss = f*x1;
diff --git a/tools/cythonize.py b/tools/cythonize.py
index 37c28fad0..f97f111d1 100755
--- a/tools/cythonize.py
+++ b/tools/cythonize.py
@@ -52,33 +52,29 @@ except NameError:
# Rules
#
def process_pyx(fromfile, tofile):
- try:
- from Cython.Compiler.Version import version as cython_version
- from distutils.version import LooseVersion
- if LooseVersion(cython_version) < LooseVersion('0.19'):
- raise Exception('Building %s requires Cython >= 0.19' % VENDOR)
-
- except ImportError:
- pass
-
flags = ['--fast-fail']
if tofile.endswith('.cxx'):
flags += ['--cplus']
try:
+ # try the cython in the installed python first (somewhat related to scipy/scipy#2397)
+ from Cython.Compiler.Version import version as cython_version
+ except ImportError:
+ # if that fails, use the one on the path, which might be the wrong version
try:
- r = subprocess.call(['cython'] + flags + ["-o", tofile, fromfile])
- if r != 0:
- raise Exception('Cython failed')
+ # Try the one on the path as a last resort
+ subprocess.check_call(
+ ['cython'] + flags + ["-o", tofile, fromfile])
except OSError:
- # There are ways of installing Cython that don't result in a cython
- # executable on the path, see scipy/scipy#2397.
- r = subprocess.call([sys.executable, '-m', 'cython'] + flags +
- ["-o", tofile, fromfile])
- if r != 0:
- raise Exception('Cython failed')
- except OSError:
- raise OSError('Cython needs to be installed')
+ raise OSError('Cython needs to be installed')
+ else:
+ # check the version, and invoke through python
+ from distutils.version import LooseVersion
+ if LooseVersion(cython_version) < LooseVersion('0.19'):
+ raise Exception('Building %s requires Cython >= 0.19' % VENDOR)
+ subprocess.check_call(
+ [sys.executable, '-m', 'cython'] + flags + ["-o", tofile, fromfile])
+
def process_tempita_pyx(fromfile, tofile):
import npy_tempita as tempita