import operator
import warnings
import sys
import decimal
from fractions import Fraction
import math
import pytest
import hypothesis
from hypothesis.extra.numpy import arrays
import hypothesis.strategies as st
from functools import partial
import numpy as np
from numpy import ma
from numpy.testing import (
assert_, assert_equal, assert_array_equal, assert_almost_equal,
assert_array_almost_equal, assert_raises, assert_allclose, IS_PYPY,
assert_warns, assert_raises_regex, suppress_warnings, HAS_REFCOUNT, IS_WASM
)
import numpy.lib.function_base as nfb
from numpy.random import rand
from numpy.lib import (
add_newdoc_ufunc, angle, average, bartlett, blackman, corrcoef, cov,
delete, diff, digitize, extract, flipud, gradient, hamming, hanning,
i0, insert, interp, kaiser, meshgrid, msort, piecewise, place, rot90,
select, setxor1d, sinc, trapz, trim_zeros, unwrap, unique, vectorize
)
from numpy.core.numeric import normalize_axis_tuple
def get_mat(n):
data = np.arange(n)
data = np.add.outer(data, data)
return data
def _make_complex(real, imag):
"""
Like real + 1j * imag, but behaves as expected when imag contains non-finite
values
"""
ret = np.zeros(np.broadcast(real, imag).shape, np.complex_)
ret.real = real
ret.imag = imag
return ret
class TestRot90:
def test_basic(self):
assert_raises(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:
def test_axes(self):
assert_raises(np.AxisError, np.flip, np.ones(4), axis=1)
assert_raises(np.AxisError, np.flip, np.ones((4, 4)), axis=2)
assert_raises(np.AxisError, np.flip, np.ones((4, 4)), axis=-3)
assert_raises(np.AxisError, np.flip, np.ones((4, 4)), axis=(0, 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))
def test_default_axis(self):
a = np.array([[1, 2, 3],
[4, 5, 6]])
b = np.array([[6, 5, 4],
[3, 2, 1]])
assert_equal(np.flip(a), b)
def test_multiple_axes(self):
a = np.array([[[0, 1],
[2, 3]],
[[4, 5],
[6, 7]]])
assert_equal(np.flip(a, axis=()), a)
b = np.array([[[5, 4],
[7, 6]],
[[1, 0],
[3, 2]]])
assert_equal(np.flip(a, axis=(0, 2)), b)
c = np.array([[[3, 2],
[1, 0]],
[[7, 6],
[5, 4]]])
assert_equal(np.flip(a, axis=(1, 2)), c)
class TestAny:
def test_basic(self):
y1 = [0, 0, 1, 0]
y2 = [0, 0, 0, 0]
y3 = [1, 0, 1, 0]
assert_(np.any(y1))
assert_(np.any(y3))
assert_(not np.any(y2))
def test_nd(self):
y1 = [[0, 0, 0], [0, 1, 0], [1, 1, 0]]
assert_(np.any(y1))
assert_array_equal(np.any(y1, axis=0), [1, 1, 0])
assert_array_equal(np.any(y1, axis=1), [0, 1, 1])
class TestAll:
def test_basic(self):
y1 = [0, 1, 1, 0]
y2 = [0, 0, 0, 0]
y3 = [1, 1, 1, 1]
assert_(not np.all(y1))
assert_(np.all(y3))
assert_(not np.all(y2))
assert_(np.all(~np.array(y2)))
def test_nd(self):
y1 = [[0, 0, 1], [0, 1, 1], [1, 1, 1]]
assert_(not np.all(y1))
assert_array_equal(np.all(y1, axis=0), [0, 0, 1])
assert_array_equal(np.all(y1, axis=1), [0, 0, 1])
class TestCopy:
def test_basic(self):
a = np.array([[1, 2], [3, 4]])
a_copy = np.copy(a)
assert_array_equal(a, a_copy)
a_copy[0, 0] = 10
assert_equal(a[0, 0], 1)
assert_equal(a_copy[0, 0], 10)
def test_order(self):
# It turns out that people rely on np.copy() preserving order by
# default; changing this broke scikit-learn:
# github.com/scikit-learn/scikit-learn/commit/7842748cf777412c506a8c0ed28090711d3a3783 # noqa
a = np.array([[1, 2], [3, 4]])
assert_(a.flags.c_contiguous)
assert_(not a.flags.f_contiguous)
a_fort = np.array([[1, 2], [3, 4]], order="F")
assert_(not a_fort.flags.c_contiguous)
assert_(a_fort.flags.f_contiguous)
a_copy = np.copy(a)
assert_(a_copy.flags.c_contiguous)
assert_(not a_copy.flags.f_contiguous)
a_fort_copy = np.copy(a_fort)
assert_(not a_fort_copy.flags.c_contiguous)
assert_(a_fort_copy.flags.f_contiguous)
def test_subok(self):
mx = ma.ones(5)
assert_(not ma.isMaskedArray(np.copy(mx, subok=False)))
assert_(ma.isMaskedArray(np.copy(mx, subok=True)))
# Default behavior
assert_(not ma.isMaskedArray(np.copy(mx)))
class TestAverage:
def test_basic(self):
y1 = np.array([1, 2, 3])
assert_(average(y1, axis=0) == 2.)
y2 = np.array([1., 2., 3.])
assert_(average(y2, axis=0) == 2.)
y3 = [0., 0., 0.]
assert_(average(y3, axis=0) == 0.)
y4 = np.ones((4, 4))
y4[0, 1] = 0
y4[1, 0] = 2
assert_almost_equal(y4.mean(0), average(y4, 0))
assert_almost_equal(y4.mean(1), average(y4, 1))
y5 = rand(5, 5)
assert_almost_equal(y5.mean(0), average(y5, 0))
assert_almost_equal(y5.mean(1), average(y5, 1))
@pytest.mark.parametrize(
'x, axis, expected_avg, weights, expected_wavg, expected_wsum',
[([1, 2, 3], None, [2.0], [3, 4, 1], [1.75], [8.0]),
([[1, 2, 5], [1, 6, 11]], 0, [[1.0, 4.0, 8.0]],
[1, 3], [[1.0, 5.0, 9.5]], [[4, 4, 4]])],
)
def test_basic_keepdims(self, x, axis, expected_avg,
weights, expected_wavg, expected_wsum):
avg = np.average(x, axis=axis, keepdims=True)
assert avg.shape == np.shape(expected_avg)
assert_array_equal(avg, expected_avg)
wavg = np.average(x, axis=axis, weights=weights, keepdims=True)
assert wavg.shape == np.shape(expected_wavg)
assert_array_equal(wavg, expected_wavg)
wavg, wsum = np.average(x, axis=axis, weights=weights, returned=True,
keepdims=True)
assert wavg.shape == np.shape(expected_wavg)
assert_array_equal(wavg, expected_wavg)
assert wsum.shape == np.shape(expected_wsum)
assert_array_equal(wsum, expected_wsum)
def test_weights(self):
y = np.arange(10)
w = np.arange(10)
actual = average(y, weights=w)
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]])
w0 = [1, 2]
actual = average(y1, weights=w0, axis=0)
desired = np.array([3., 4., 5.])
assert_almost_equal(actual, desired)
w1 = [0, 0, 1]
actual = average(y1, weights=w1, axis=1)
desired = np.array([3., 6.])
assert_almost_equal(actual, desired)
# This should raise an error. Can we test for that ?
# assert_equal(average(y1, weights=w1), 9./2.)
# 2D Case
w2 = [[0, 0, 1], [0, 0, 2]]
desired = np.array([3., 6.])
assert_array_equal(average(y1, weights=w2, axis=1), desired)
assert_equal(average(y1, weights=w2), 5.)
y3 = rand(5).astype(np.float32)
w3 = rand(5).astype(np.float64)
assert_(np.average(y3, weights=w3).dtype == np.result_type(y3, w3))
# test weights with `keepdims=False` and `keepdims=True`
x = np.array([2, 3, 4]).reshape(3, 1)
w = np.array([4, 5, 6]).reshape(3, 1)
actual = np.average(x, weights=w, axis=1, keepdims=False)
desired = np.array([2., 3., 4.])
assert_array_equal(actual, desired)
actual = np.average(x, weights=w, axis=1, keepdims=True)
desired = np.array([[2.], [3.], [4.]])
assert_array_equal(actual, desired)
def test_returned(self):
y = np.array([[1, 2, 3], [4, 5, 6]])
# No weights
avg, scl = average(y, returned=True)
assert_equal(scl, 6.)
avg, scl = average(y, 0, returned=True)
assert_array_equal(scl, np.array([2., 2., 2.]))
avg, scl = average(y, 1, returned=True)
assert_array_equal(scl, np.array([3., 3.]))
# With weights
w0 = [1, 2]
avg, scl = average(y, weights=w0, axis=0, returned=True)
assert_array_equal(scl, np.array([3., 3., 3.]))
w1 = [1, 2, 3]
avg, scl = average(y, weights=w1, axis=1, returned=True)
assert_array_equal(scl, np.array([6., 6.]))
w2 = [[0, 0, 1], [1, 2, 3]]
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)
assert_equal(type(np.average(a)), subclass)
assert_equal(type(np.average(a, weights=w)), subclass)
def test_upcasting(self):
typs = [('i4', 'i4', 'f8'), ('i4', 'f4', 'f8'), ('f4', 'i4', 'f8'),
('f4', 'f4', 'f4'), ('f4', 'f8', 'f8')]
for at, wt, rt in typs:
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))
def test_object_dtype(self):
a = np.array([decimal.Decimal(x) for x in range(10)])
w = np.array([decimal.Decimal(1) for _ in range(10)])
w /= w.sum()
assert_almost_equal(a.mean(0), average(a, weights=w))
def test_average_class_without_dtype(self):
# see gh-21988
a = np.array([Fraction(1, 5), Fraction(3, 5)])
assert_equal(np.average(a), Fraction(2, 5))
class TestSelect:
choices = [np.array([1, 2, 3]),
np.array([4, 5, 6]),
np.array([7, 8, 9])]
conditions = [np.array([False, False, False]),
np.array([False, True, False]),
np.array([False, False, True])]
def _select(self, cond, values, default=0):
output = []
for m in range(len(cond)):
output += [V[m] for V, C in zip(values, cond) if C[m]] or [default]
return output
def test_basic(self):
choices = self.choices
conditions = self.conditions
assert_array_equal(select(conditions, choices, default=15),
self._select(conditions, choices, default=15))
assert_equal(len(choices), 3)
assert_equal(len(conditions), 3)
def test_broadcasting(self):
conditions = [np.array(True), np.array([False, True, False])]
choices = [1, np.arange(12).reshape(4, 3)]
assert_array_equal(select(conditions, choices), np.ones((4, 3)))
# default can broadcast too:
assert_equal(select([True], [0], default=[0]).shape, (1,))
def test_return_dtype(self):
assert_equal(select(self.conditions, self.choices, 1j).dtype,
np.complex_)
# But the conditions need to be stronger then the scalar default
# if it is scalar.
choices = [choice.astype(np.int8) for choice in self.choices]
assert_equal(select(self.conditions, choices).dtype, np.int8)
d = np.array([1, 2, 3, np.nan, 5, 7])
m = np.isnan(d)
assert_equal(select([m], [d]), [0, 0, 0, np.nan, 0, 0])
def test_deprecated_empty(self):
assert_raises(ValueError, select, [], [], 3j)
assert_raises(ValueError, select, [], [])
def test_non_bool_deprecation(self):
choices = self.choices
conditions = self.conditions[:]
conditions[0] = conditions[0].astype(np.int_)
assert_raises(TypeError, select, conditions, choices)
conditions[0] = conditions[0].astype(np.uint8)
assert_raises(TypeError, select, conditions, choices)
assert_raises(TypeError, select, conditions, choices)
def test_many_arguments(self):
# This used to be limited by NPY_MAXARGS == 32
conditions = [np.array([False])] * 100
choices = [np.array([1])] * 100
select(conditions, choices)
class TestInsert:
def test_basic(self):
a = [1, 2, 3]
assert_equal(insert(a, 0, 1), [1, 1, 2, 3])
assert_equal(insert(a, 3, 1), [1, 2, 3, 1])
assert_equal(insert(a, [1, 1, 1], [1, 2, 3]), [1, 1, 2, 3, 2, 3])
assert_equal(insert(a, 1, [1, 2, 3]), [1, 1, 2, 3, 2, 3])
assert_equal(insert(a, [1, -1, 3], 9), [1, 9, 2, 9, 3, 9])
assert_equal(insert(a, slice(-1, None, -1), 9), [9, 1, 9, 2, 9, 3])
assert_equal(insert(a, [-1, 1, 3], [7, 8, 9]), [1, 8, 2, 7, 3, 9])
b = np.array([0, 1], dtype=np.float64)
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])
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])
assert_(w[0].category is FutureWarning)
def test_multidim(self):
a = [[1, 1, 1]]
r = [[2, 2, 2],
[1, 1, 1]]
assert_equal(insert(a, 0, [1]), [1, 1, 1, 1])
assert_equal(insert(a, 0, [2, 2, 2], axis=0), r)
assert_equal(insert(a, 0, 2, axis=0), r)
assert_equal(insert(a, 2, 2, axis=1), [[1, 1, 2, 1]])
a = np.array([[1, 1], [2, 2], [3, 3]])
b = np.arange(1, 4).repeat(3).reshape(3, 3)
c = np.concatenate(
(a[:, 0:1], np.arange(1, 4).repeat(3).reshape(3, 3).T,
a[:, 1:2]), axis=1)
assert_equal(insert(a, [1], [[1], [2], [3]], axis=1), b)
assert_equal(insert(a, [1], [1, 2, 3], axis=1), c)
# scalars behave differently, in this case exactly opposite:
assert_equal(insert(a, 1, [1, 2, 3], axis=1), b)
assert_equal(insert(a, 1, [[1], [2], [3]], axis=1), c)
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)
# 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))
# invalid axis value
assert_raises(np.AxisError, insert, a, 1, a[:, 2, :], axis=3)
assert_raises(np.AxisError, 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))
def test_0d(self):
a = np.array(1)
with pytest.raises(np.AxisError):
insert(a, [], 2, axis=0)
with pytest.raises(TypeError):
insert(a, [], 2, axis="nonsense")
def test_subclass(self):
class SubClass(np.ndarray):
pass
a = np.arange(10).view(SubClass)
assert_(isinstance(np.insert(a, 0, [0]), SubClass))
assert_(isinstance(np.insert(a, [], []), SubClass))
assert_(isinstance(np.insert(a, [0, 1], [1, 2]), SubClass))
assert_(isinstance(np.insert(a, slice(1, 2), [1, 2]), SubClass))
assert_(isinstance(np.insert(a, slice(1, -2, -1), []), SubClass))
# This is an error in the future:
a = np.array(1).view(SubClass)
assert_(isinstance(np.insert(a, 0, [0]), SubClass))
def test_index_array_copied(self):
x = np.array([1, 1, 1])
np.insert([0, 1, 2], x, [3, 4, 5])
assert_equal(x, np.array([1, 1, 1]))
def test_structured_array(self):
a = np.array([(1, 'a'), (2, 'b'), (3, 'c')],
dtype=[('foo', 'i'), ('bar', 'a1')])
val = (4, 'd')
b = np.insert(a, 0, val)
assert_array_equal(b[0], np.array(val, dtype=b.dtype))
val = [(4, 'd')] * 2
b = np.insert(a, [0, 2], val)
assert_array_equal(b[[0, 3]], np.array(val, dtype=b.dtype))
def test_index_floats(self):
with pytest.raises(IndexError):
np.insert([0, 1, 2], np.array([1.0, 2.0]), [10, 20])
with pytest.raises(IndexError):
np.insert([0, 1, 2], np.array([], dtype=float), [])
@pytest.mark.parametrize('idx', [4, -4])
def test_index_out_of_bounds(self, idx):
with pytest.raises(IndexError, match='out of bounds'):
np.insert([0, 1, 2], [idx], [3, 4])
class TestAmax:
def test_basic(self):
a = [3, 4, 5, 10, -3, -5, 6.0]
assert_equal(np.amax(a), 10.0)
b = [[3, 6.0, 9.0],
[4, 10.0, 5.0],
[8, 3.0, 2.0]]
assert_equal(np.amax(b, axis=0), [8.0, 10.0, 9.0])
assert_equal(np.amax(b, axis=1), [9.0, 10.0, 8.0])
class TestAmin:
def test_basic(self):
a = [3, 4, 5, 10, -3, -5, 6.0]
assert_equal(np.amin(a), -5.0)
b = [[3, 6.0, 9.0],
[4, 10.0, 5.0],
[8, 3.0, 2.0]]
assert_equal(np.amin(b, axis=0), [3.0, 3.0, 2.0])
assert_equal(np.amin(b, axis=1), [3.0, 4.0, 2.0])
class TestPtp:
def test_basic(self):
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])
assert_equal(b.ptp(axis=0, keepdims=True), [[5.0, 7.0, 7.0]])
assert_equal(b.ptp(axis=(0,1), keepdims=True), [[8.0]])
class TestCumsum:
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]]
for ctype in [np.int8, np.uint8, np.int16, np.uint16, np.int32,
np.uint32, np.float32, np.float64, np.complex64,
np.complex128]:
a = np.array(ba, ctype)
a2 = np.array(ba2, ctype)
tgt = np.array([1, 3, 13, 24, 30, 35, 39], ctype)
assert_array_equal(np.cumsum(a, axis=0), tgt)
tgt = np.array(
[[1, 2, 3, 4], [6, 8, 10, 13], [16, 11, 14, 18]], ctype)
assert_array_equal(np.cumsum(a2, axis=0), tgt)
tgt = np.array(
[[1, 3, 6, 10], [5, 11, 18, 27], [10, 13, 17, 22]], ctype)
assert_array_equal(np.cumsum(a2, axis=1), tgt)
class TestProd:
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]]
for ctype in [np.int16, np.uint16, np.int32, np.uint32,
np.float32, np.float64, np.complex64, np.complex128]:
a = np.array(ba, ctype)
a2 = np.array(ba2, ctype)
if ctype in ['1', 'b']:
assert_raises(ArithmeticError, np.prod, a)
assert_raises(ArithmeticError, np.prod, a2, 1)
else:
assert_equal(a.prod(axis=0), 26400)
assert_array_equal(a2.prod(axis=0),
np.array([50, 36, 84, 180], ctype))
assert_array_equal(a2.prod(axis=-1),
np.array([24, 1890, 600], ctype))
class TestCumprod:
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]]
for ctype in [np.int16, np.uint16, np.int32, np.uint32,
np.float32, np.float64, np.complex64, np.complex128]:
a = np.array(ba, ctype)
a2 = np.array(ba2, ctype)
if ctype in ['1', 'b']:
assert_raises(ArithmeticError, np.cumprod, a)
assert_raises(ArithmeticError, np.cumprod, a2, 1)
assert_raises(ArithmeticError, np.cumprod, a)
else:
assert_array_equal(np.cumprod(a, axis=-1),
np.array([1, 2, 20, 220,
1320, 6600, 26400], ctype))
assert_array_equal(np.cumprod(a2, axis=0),
np.array([[1, 2, 3, 4],
[5, 12, 21, 36],
[50, 36, 84, 180]], ctype))
assert_array_equal(np.cumprod(a2, axis=-1),
np.array([[1, 2, 6, 24],
[5, 30, 210, 1890],
[10, 30, 120, 600]], ctype))
class TestDiff:
def test_basic(self):
x = [1, 4, 6, 7, 12]
out = np.array([3, 2, 1, 5])
out2 = np.array([-1, -1, 4])
out3 = np.array([0, 5])
assert_array_equal(diff(x), out)
assert_array_equal(diff(x, n=2), out2)
assert_array_equal(diff(x, n=3), out3)
x = [1.1, 2.2, 3.0, -0.2, -0.1]
out = np.array([1.1, 0.8, -3.2, 0.1])
assert_almost_equal(diff(x), out)
x = [True, True, False, False]
out = np.array([False, True, False])
out2 = np.array([True, True])
assert_array_equal(diff(x), out)
assert_array_equal(diff(x, n=2), out2)
def test_axis(self):
x = np.zeros((10, 20, 30))
x[:, 1::2, :] = 1
exp = np.ones((10, 19, 30))
exp[:, 1::2, :] = -1
assert_array_equal(diff(x), np.zeros((10, 20, 29)))
assert_array_equal(diff(x, axis=-1), np.zeros((10, 20, 29)))
assert_array_equal(diff(x, axis=0), np.zeros((9, 20, 30)))
assert_array_equal(diff(x, axis=1), exp)
assert_array_equal(diff(x, axis=-2), exp)
assert_raises(np.AxisError, diff, x, axis=3)
assert_raises(np.AxisError, diff, x, axis=-4)
x = np.array(1.11111111111, np.float64)
assert_raises(ValueError, diff, x)
def test_nd(self):
x = 20 * rand(10, 20, 30)
out1 = x[:, :, 1:] - x[:, :, :-1]
out2 = out1[:, :, 1:] - out1[:, :, :-1]
out3 = x[1:, :, :] - x[:-1, :, :]
out4 = out3[1:, :, :] - out3[:-1, :, :]
assert_array_equal(diff(x), out1)
assert_array_equal(diff(x, n=2), out2)
assert_array_equal(diff(x, axis=0), out3)
assert_array_equal(diff(x, n=2, axis=0), out4)
def test_n(self):
x = list(range(3))
assert_raises(ValueError, diff, x, n=-1)
output = [diff(x, n=n) for n in range(1, 5)]
expected = [[1, 1], [0], [], []]
assert_(diff(x, n=0) is x)
for n, (expected, out) in enumerate(zip(expected, output), start=1):
assert_(type(out) is np.ndarray)
assert_array_equal(out, expected)
assert_equal(out.dtype, np.int_)
assert_equal(len(out), max(0, len(x) - n))
def test_times(self):
x = np.arange('1066-10-13', '1066-10-16', dtype=np.datetime64)
expected = [
np.array([1, 1], dtype='timedelta64[D]'),
np.array([0], dtype='timedelta64[D]'),
]
expected.extend([np.array([], dtype='timedelta64[D]')] * 3)
for n, exp in enumerate(expected, start=1):
out = diff(x, n=n)
assert_array_equal(out, exp)
assert_equal(out.dtype, exp.dtype)
def test_subclass(self):
x = ma.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]],
mask=[[False, False], [True, False],
[False, True], [True, True], [False, False]])
out = diff(x)
assert_array_equal(out.data, [[1], [1], [1], [1], [1]])
assert_array_equal(out.mask, [[False], [True],
[True], [True], [False]])
assert_(type(out) is type(x))
out3 = diff(x, n=3)
assert_array_equal(out3.data, [[], [], [], [], []])
assert_array_equal(out3.mask, [[], [], [], [], []])
assert_(type(out3) is type(x))
def test_prepend(self):
x = np.arange(5) + 1
assert_array_equal(diff(x, prepend=0), np.ones(5))
assert_array_equal(diff(x, prepend=[0]), np.ones(5))
assert_array_equal(np.cumsum(np.diff(x, prepend=0)), x)
assert_array_equal(diff(x, prepend=[-1, 0]), np.ones(6))
x = np.arange(4).reshape(2, 2)
result = np.diff(x, axis=1, prepend=0)
expected = [[0, 1], [2, 1]]
assert_array_equal(result, expected)
result = np.diff(x, axis=1, prepend=[[0], [0]])
assert_array_equal(result, expected)
result = np.diff(x, axis=0, prepend=0)
expected = [[0, 1], [2, 2]]
assert_array_equal(result, expected)
result = np.diff(x, axis=0, prepend=[[0, 0]])
assert_array_equal(result, expected)
assert_raises(ValueError, np.diff, x, prepend=np.zeros((3,3)))
assert_raises(np.AxisError, diff, x, prepend=0, axis=3)
def test_append(self):
x = np.arange(5)
result = diff(x, append=0)
expected = [1, 1, 1, 1, -4]
assert_array_equal(result, expected)
result = diff(x, append=[0])
assert_array_equal(result, expected)
result = diff(x, append=[0, 2])
expected = expected + [2]
assert_array_equal(result, expected)
x = np.arange(4).reshape(2, 2)
result = np.diff(x, axis=1, append=0)
expected = [[1, -1], [1, -3]]
assert_array_equal(result, expected)
result = np.diff(x, axis=1, append=[[0], [0]])
assert_array_equal(result, expected)
result = np.diff(x, axis=0, append=0)
expected = [[2, 2], [-2, -3]]
assert_array_equal(result, expected)
result = np.diff(x, axis=0, append=[[0, 0]])
assert_array_equal(result, expected)
assert_raises(ValueError, np.diff, x, append=np.zeros((3,3)))
assert_raises(np.AxisError, diff, x, append=0, axis=3)
class TestDelete:
def setup_method(self):
self.a = np.arange(5)
self.nd_a = np.arange(5).repeat(2).reshape(1, 5, 2)
def _check_inverse_of_slicing(self, indices):
a_del = delete(self.a, indices)
nd_a_del = delete(self.nd_a, indices, axis=1)
msg = 'Delete failed for obj: %r' % indices
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)
def test_slices(self):
lims = [-6, -2, 0, 1, 2, 4, 5]
steps = [-3, -1, 1, 3]
for start in lims:
for stop in lims:
for step in steps:
s = slice(start, stop, step)
self._check_inverse_of_slicing(s)
def test_fancy(self):
self._check_inverse_of_slicing(np.array([[0, 1], [2, 1]]))
with pytest.raises(IndexError):
delete(self.a, [100])
with pytest.raises(IndexError):
delete(self.a, [-100])
self._check_inverse_of_slicing([0, -1, 2, 2])
self._check_inverse_of_slicing([True, False, False, True, False])
# not legal, indexing with these would change the dimension
with pytest.raises(ValueError):
delete(self.a, True)
with pytest.raises(ValueError):
delete(self.a, False)
# not enough items
with pytest.raises(ValueError):
delete(self.a, [False]*4)
def test_single(self):
self._check_inverse_of_slicing(0)
self._check_inverse_of_slicing(-4)
def test_0d(self):
a = np.array(1)
with pytest.raises(np.AxisError):
delete(a, [], axis=0)
with pytest.raises(TypeError):
delete(a, [], axis="nonsense")
def test_subclass(self):
class SubClass(np.ndarray):
pass
a = self.a.view(SubClass)
assert_(isinstance(delete(a, 0), SubClass))
assert_(isinstance(delete(a, []), SubClass))
assert_(isinstance(delete(a, [0, 1]), SubClass))
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)
def test_index_floats(self):
with pytest.raises(IndexError):
np.delete([0, 1, 2], np.array([1.0, 2.0]))
with pytest.raises(IndexError):
np.delete([0, 1, 2], np.array([], dtype=float))
@pytest.mark.parametrize("indexer", [np.array([1]), [1]])
def test_single_item_array(self, indexer):
a_del_int = delete(self.a, 1)
a_del = delete(self.a, indexer)
assert_equal(a_del_int, a_del)
nd_a_del_int = delete(self.nd_a, 1, axis=1)
nd_a_del = delete(self.nd_a, np.array([1]), axis=1)
assert_equal(nd_a_del_int, nd_a_del)
def test_single_item_array_non_int(self):
# Special handling for integer arrays must not affect non-integer ones.
# If `False` was cast to `0` it would delete the element:
res = delete(np.ones(1), np.array([False]))
assert_array_equal(res, np.ones(1))
# Test the more complicated (with axis) case from gh-21840
x = np.ones((3, 1))
false_mask = np.array([False], dtype=bool)
true_mask = np.array([True], dtype=bool)
res = delete(x, false_mask, axis=-1)
assert_array_equal(res, x)
res = delete(x, true_mask, axis=-1)
assert_array_equal(res, x[:, :0])
# Object or e.g. timedeltas should *not* be allowed
with pytest.raises(IndexError):
delete(np.ones(2), np.array([0], dtype=object))
with pytest.raises(IndexError):
# timedeltas are sometimes "integral, but clearly not allowed:
delete(np.ones(2), np.array([0], dtype="m8[ns]"))
class TestGradient:
def test_basic(self):
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), dx)
assert_array_equal(gradient(v), dx)
def test_args(self):
dx = np.cumsum(np.ones(5))
dx_uneven = [1., 2., 5., 9., 11.]
f_2d = np.arange(25).reshape(5, 5)
# distances must be scalars or have size equal to gradient[axis]
gradient(np.arange(5), 3.)
gradient(np.arange(5), np.array(3.))
gradient(np.arange(5), dx)
# dy is set equal to dx because scalar
gradient(f_2d, 1.5)
gradient(f_2d, np.array(1.5))
gradient(f_2d, dx_uneven, dx_uneven)
# mix between even and uneven spaces and
# mix between scalar and vector
gradient(f_2d, dx, 2)
# 2D but axis specified
gradient(f_2d, dx, axis=1)
# 2d coordinate arguments are not yet allowed
assert_raises_regex(ValueError, '.*scalars or 1d',
gradient, f_2d, np.stack([dx]*2, axis=-1), 1)
def test_badargs(self):
f_2d = np.arange(25).reshape(5, 5)
x = np.cumsum(np.ones(5))
# wrong sizes
assert_raises(ValueError, gradient, f_2d, x, np.ones(2))
assert_raises(ValueError, gradient, f_2d, 1, np.ones(2))
assert_raises(ValueError, gradient, f_2d, np.ones(2), np.ones(2))
# wrong number of arguments
assert_raises(TypeError, gradient, f_2d, x)
assert_raises(TypeError, gradient, f_2d, x, axis=(0,1))
assert_raises(TypeError, gradient, f_2d, x, x, x)
assert_raises(TypeError, gradient, f_2d, 1, 1, 1)
assert_raises(TypeError, gradient, f_2d, x, x, axis=1)
assert_raises(TypeError, gradient, f_2d, 1, 1, axis=1)
def test_datetime64(self):
# Make sure gradient() can handle special types like datetime64
x = np.array(
['1910-08-16', '1910-08-11', '1910-08-10', '1910-08-12',
'1910-10-12', '1910-12-12', '1912-12-12'],
dtype='datetime64[D]')
dx = np.array(
[-5, -3, 0, 31, 61, 396, 731],
dtype='timedelta64[D]')
assert_array_equal(gradient(x), dx)
assert_(dx.dtype == np.dtype('timedelta64[D]'))
def test_masked(self):
# Make sure that gradient supports subclasses like masked arrays
x = np.ma.array([[1, 1], [3, 4]],
mask=[[False, False], [False, False]])
out = gradient(x)[0]
assert_equal(type(out), type(x))
# And make sure that the output and input don't have aliased mask
# arrays
assert_(x._mask is not out._mask)
# Also check that edge_order=2 doesn't alter the original mask
x2 = np.ma.arange(5)
x2[2] = np.ma.masked
np.gradient(x2, edge_order=2)
assert_array_equal(x2.mask, [False, False, True, False, False])
def test_second_order_accurate(self):
# Testing that the relative numerical error is less that 3% for
# this example problem. This corresponds to second order
# accurate finite differences for all interior and boundary
# points.
x = np.linspace(0, 1, 10)
dx = x[1] - x[0]
y = 2 * x ** 3 + 4 * x ** 2 + 2 * x
analytical = 6 * x ** 2 + 8 * x + 2
num_error = np.abs((np.gradient(y, dx, edge_order=2) / analytical) - 1)
assert_(np.all(num_error < 0.03) == True)
# test with unevenly spaced
np.random.seed(0)
x = np.sort(np.random.random(10))
y = 2 * x ** 3 + 4 * x ** 2 + 2 * x
analytical = 6 * x ** 2 + 8 * x + 2
num_error = np.abs((np.gradient(y, x, edge_order=2) / analytical) - 1)
assert_(np.all(num_error < 0.03) == True)
def test_spacing(self):
f = np.array([0, 2., 3., 4., 5., 5.])
f = np.tile(f, (6,1)) + f.reshape(-1, 1)
x_uneven = np.array([0., 0.5, 1., 3., 5., 7.])
x_even = np.arange(6.)
fdx_even_ord1 = np.tile([2., 1.5, 1., 1., 0.5, 0.], (6,1))
fdx_even_ord2 = np.tile([2.5, 1.5, 1., 1., 0.5, -0.5], (6,1))
fdx_uneven_ord1 = np.tile([4., 3., 1.7, 0.5, 0.25, 0.], (6,1))
fdx_uneven_ord2 = np.tile([5., 3., 1.7, 0.5, 0.25, -0.25], (6,1))
# evenly spaced
for edge_order, exp_res in [(1, fdx_even_ord1), (2, fdx_even_ord2)]:
res1 = gradient(f, 1., axis=(0,1), edge_order=edge_order)
res2 = gradient(f, x_even, x_even,
axis=(0,1), edge_order=edge_order)
res3 = gradient(f, x_even, x_even,
axis=None, edge_order=edge_order)
assert_array_equal(res1, res2)
assert_array_equal(res2, res3)
assert_almost_equal(res1[0], exp_res.T)
assert_almost_equal(res1[1], exp_res)
res1 = gradient(f, 1., axis=0, edge_order=edge_order)
res2 = gradient(f, x_even, axis=0, edge_order=edge_order)
assert_(res1.shape == res2.shape)
assert_almost_equal(res2, exp_res.T)
res1 = gradient(f, 1., axis=1, edge_order=edge_order)
res2 = gradient(f, x_even, axis=1, edge_order=edge_order)
assert_(res1.shape == res2.shape)
assert_array_equal(res2, exp_res)
# unevenly spaced
for edge_order, exp_res in [(1, fdx_uneven_ord1), (2, fdx_uneven_ord2)]:
res1 = gradient(f, x_uneven, x_uneven,
axis=(0,1), edge_order=edge_order)
res2 = gradient(f, x_uneven, x_uneven,
axis=None, edge_order=edge_order)
assert_array_equal(res1, res2)
assert_almost_equal(res1[0], exp_res.T)
assert_almost_equal(res1[1], exp_res)
res1 = gradient(f, x_uneven, axis=0, edge_order=edge_order)
assert_almost_equal(res1, exp_res.T)
res1 = gradient(f, x_uneven, axis=1, edge_order=edge_order)
assert_almost_equal(res1, exp_res)
# mixed
res1 = gradient(f, x_even, x_uneven, axis=(0,1), edge_order=1)
res2 = gradient(f, x_uneven, x_even, axis=(1,0), edge_order=1)
assert_array_equal(res1[0], res2[1])
assert_array_equal(res1[1], res2[0])
assert_almost_equal(res1[0], fdx_even_ord1.T)
assert_almost_equal(res1[1], fdx_uneven_ord1)
res1 = gradient(f, x_even, x_uneven, axis=(0,1), edge_order=2)
res2 = gradient(f, x_uneven, x_even, axis=(1,0), edge_order=2)
assert_array_equal(res1[0], res2[1])
assert_array_equal(res1[1], res2[0])
assert_almost_equal(res1[0], fdx_even_ord2.T)
assert_almost_equal(res1[1], fdx_uneven_ord2)
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(TypeError, gradient, x, 1, 2, axis=1)
assert_raises(np.AxisError, gradient, x, axis=3)
assert_raises(np.AxisError, gradient, x, axis=-3)
# assert_raises(TypeError, gradient, x, axis=[1,])
def test_timedelta64(self):
# Make sure gradient() can handle special types like timedelta64
x = np.array(
[-5, -3, 10, 12, 61, 321, 300],
dtype='timedelta64[D]')
dx = np.array(
[2, 7, 7, 25, 154, 119, -21],
dtype='timedelta64[D]')
assert_array_equal(gradient(x), dx)
assert_(dx.dtype == np.dtype('timedelta64[D]'))
def test_inexact_dtypes(self):
for dt in [np.float16, np.float32, np.float64]:
# dtypes should not be promoted in a different way to what diff does
x = np.array([1, 2, 3], dtype=dt)
assert_equal(gradient(x).dtype, np.diff(x).dtype)
def test_values(self):
# needs at least 2 points for edge_order ==1
gradient(np.arange(2), edge_order=1)
# needs at least 3 points for edge_order ==1
gradient(np.arange(3), edge_order=2)
assert_raises(ValueError, gradient, np.arange(0), edge_order=1)
assert_raises(ValueError, gradient, np.arange(0), edge_order=2)
assert_raises(ValueError, gradient, np.arange(1), edge_order=1)
assert_raises(ValueError, gradient, np.arange(1), edge_order=2)
assert_raises(ValueError, gradient, np.arange(2), edge_order=2)
@pytest.mark.parametrize('f_dtype', [np.uint8, np.uint16,
np.uint32, np.uint64])
def test_f_decreasing_unsigned_int(self, f_dtype):
f = np.array([5, 4, 3, 2, 1], dtype=f_dtype)
g = gradient(f)
assert_array_equal(g, [-1]*len(f))
@pytest.mark.parametrize('f_dtype', [np.int8, np.int16,
np.int32, np.int64])
def test_f_signed_int_big_jump(self, f_dtype):
maxint = np.iinfo(f_dtype).max
x = np.array([1, 3])
f = np.array([-1, maxint], dtype=f_dtype)
dfdx = gradient(f, x)
assert_array_equal(dfdx, [(maxint + 1) // 2]*2)
@pytest.mark.parametrize('x_dtype', [np.uint8, np.uint16,
np.uint32, np.uint64])
def test_x_decreasing_unsigned(self, x_dtype):
x = np.array([3, 2, 1], dtype=x_dtype)
f = np.array([0, 2, 4])
dfdx = gradient(f, x)
assert_array_equal(dfdx, [-2]*len(x))
@pytest.mark.parametrize('x_dtype', [np.int8, np.int16,
np.int32, np.int64])
def test_x_signed_int_big_jump(self, x_dtype):
minint = np.iinfo(x_dtype).min
maxint = np.iinfo(x_dtype).max
x = np.array([-1, maxint], dtype=x_dtype)
f = np.array([minint // 2, 0])
dfdx = gradient(f, x)
assert_array_equal(dfdx, [0.5, 0.5])
def test_return_type(self):
res = np.gradient(([1, 2], [2, 3]))
if np._using_numpy2_behavior():
assert type(res) is tuple
else:
assert type(res) is list
class TestAngle:
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]
y = angle(x)
yo = [
np.arctan(3.0 / 1.0),
np.arctan(1.0), 0, np.pi / 2, np.pi, -np.pi / 2.0,
-np.arctan(3.0 / 1.0), np.pi - np.arctan(3.0 / 1.0)]
z = angle(x, deg=True)
zo = np.array(yo) * 180 / np.pi
assert_array_almost_equal(y, yo, 11)
assert_array_almost_equal(z, zo, 11)
def test_subclass(self):
x = np.ma.array([1 + 3j, 1, np.sqrt(2)/2 * (1 + 1j)])
x[1] = np.ma.masked
expected = np.ma.array([np.arctan(3.0 / 1.0), 0, np.arctan(1.0)])
expected[1] = np.ma.masked
actual = angle(x)
assert_equal(type(actual), type(expected))
assert_equal(actual.mask, expected.mask)
assert_equal(actual, expected)
class TestTrimZeros:
a = np.array([0, 0, 1, 0, 2, 3, 4, 0])
b = a.astype(float)
c = a.astype(complex)
d = a.astype(object)
def values(self):
attr_names = ('a', 'b', 'c', 'd')
return (getattr(self, name) for name in attr_names)
def test_basic(self):
slc = np.s_[2:-1]
for arr in self.values():
res = trim_zeros(arr)
assert_array_equal(res, arr[slc])
def test_leading_skip(self):
slc = np.s_[:-1]
for arr in self.values():
res = trim_zeros(arr, trim='b')
assert_array_equal(res, arr[slc])
def test_trailing_skip(self):
slc = np.s_[2:]
for arr in self.values():
res = trim_zeros(arr, trim='F')
assert_array_equal(res, arr[slc])
def test_all_zero(self):
for _arr in self.values():
arr = np.zeros_like(_arr, dtype=_arr.dtype)
res1 = trim_zeros(arr, trim='B')
assert len(res1) == 0
res2 = trim_zeros(arr, trim='f')
assert len(res2) == 0
def test_size_zero(self):
arr = np.zeros(0)
res = trim_zeros(arr)
assert_array_equal(arr, res)
@pytest.mark.parametrize(
'arr',
[np.array([0, 2**62, 0]),
np.array([0, 2**63, 0]),
np.array([0, 2**64, 0])]
)
def test_overflow(self, arr):
slc = np.s_[1:2]
res = trim_zeros(arr)
assert_array_equal(res, arr[slc])
def test_no_trim(self):
arr = np.array([None, 1, None])
res = trim_zeros(arr)
assert_array_equal(arr, res)
def test_list_to_list(self):
res = trim_zeros(self.a.tolist())
assert isinstance(res, list)
class TestExtins:
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
ac = a.copy()
c = extract(mask, a)
place(a, mask, 0)
place(a, mask, c)
assert_array_equal(a, ac)
# _foo1 and _foo2 are used in some tests in TestVectorize.
def _foo1(x, y=1.0):
return y*math.floor(x)
def _foo2(x, y=1.0, z=0.0):
return y*math.floor(x) + z
class TestVectorize:
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])
def test_scalar(self):
def addsubtract(a, b):
if a > b:
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])
def test_large(self):
x = np.linspace(-3, 2, 10000)
f = vectorize(lambda x: x)
y = f(x)
assert_array_equal(y, x)
def test_ufunc(self):
f = vectorize(math.cos)
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_almost_equal(r1, r2)
def test_keywords(self):
def foo(a, b=1):
return a + b
f = vectorize(foo)
args = np.array([1, 2, 3])
r1 = f(args)
r2 = np.array([2, 3, 4])
assert_array_equal(r1, r2)
r1 = f(args, 2)
r2 = np.array([3, 4, 5])
assert_array_equal(r1, r2)
def test_keywords_with_otypes_order1(self):
# gh-1620: The second call of f would crash with
# `ValueError: invalid number of arguments`.
f = vectorize(_foo1, otypes=[float])
# We're testing the caching of ufuncs by vectorize, so the order
# of these function calls is an important part of the test.
r1 = f(np.arange(3.0), 1.0)
r2 = f(np.arange(3.0))
assert_array_equal(r1, r2)
def test_keywords_with_otypes_order2(self):
# gh-1620: The second call of f would crash with
# `ValueError: non-broadcastable output operand with shape ()
# doesn't match the broadcast shape (3,)`.
f = vectorize(_foo1, otypes=[float])
# We're testing the caching of ufuncs by vectorize, so the order
# of these function calls is an important part of the test.
r1 = f(np.arange(3.0))
r2 = f(np.arange(3.0), 1.0)
assert_array_equal(r1, r2)
def test_keywords_with_otypes_order3(self):
# gh-1620: The third call of f would crash with
# `ValueError: invalid number of arguments`.
f = vectorize(_foo1, otypes=[float])
# We're testing the caching of ufuncs by vectorize, so the order
# of these function calls is an important part of the test.
r1 = f(np.arange(3.0))
r2 = f(np.arange(3.0), y=1.0)
r3 = f(np.arange(3.0))
assert_array_equal(r1, r2)
assert_array_equal(r1, r3)
def test_keywords_with_otypes_several_kwd_args1(self):
# gh-1620 Make sure different uses of keyword arguments
# don't break the vectorized function.
f = vectorize(_foo2, otypes=[float])
# We're testing the caching of ufuncs by vectorize, so the order
# of these function calls is an important part of the test.
r1 = f(10.4, z=100)
r2 = f(10.4, y=-1)
r3 = f(10.4)
assert_equal(r1, _foo2(10.4, z=100))
assert_equal(r2, _foo2(10.4, y=-1))
assert_equal(r3, _foo2(10.4))
def test_keywords_with_otypes_several_kwd_args2(self):
# gh-1620 Make sure different uses of keyword arguments
# don't break the vectorized function.
f = vectorize(_foo2, otypes=[float])
# We're testing the caching of ufuncs by vectorize, so the order
# of these function calls is an important part of the test.
r1 = f(z=100, x=10.4, y=-1)
r2 = f(1, 2, 3)
assert_equal(r1, _foo2(z=100, x=10.4, y=-1))
assert_equal(r2, _foo2(1, 2, 3))
def test_keywords_no_func_code(self):
# This needs to test a function that has keywords but
# no func_code attribute, since otherwise vectorize will
# inspect the func_code.
import random
try:
vectorize(random.randrange) # Should succeed
except Exception:
raise AssertionError()
def test_keywords2_ticket_2100(self):
# 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)
r2 = np.array([2, 3, 4])
assert_array_equal(r1, r2)
r1 = f(b=1, a=args)
assert_array_equal(r1, r2)
r1 = f(args, b=2)
r2 = np.array([3, 4, 5])
assert_array_equal(r1, r2)
def test_keywords3_ticket_2100(self):
# 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)
return res
vpolyval = np.vectorize(mypolyval, excluded=['p', 1])
ans = [3, 6]
assert_array_equal(ans, vpolyval(x=[0, 1], p=[1, 2, 3]))
assert_array_equal(ans, vpolyval([0, 1], p=[1, 2, 3]))
assert_array_equal(ans, vpolyval([0, 1], [1, 2, 3]))
def test_keywords4_ticket_2100(self):
# 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.
@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
class Foo:
b = 2
def bar(self, a):
return a ** self.b
assert_array_equal(vectorize(Foo().bar)(np.arange(9)),
np.arange(9) ** 2)
assert_array_equal(vectorize(Foo.bar)(Foo(), np.arange(9)),
np.arange(9) ** 2)
def test_execution_order_ticket_1487(self):
# 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))
f2 = vectorize(lambda x: x)
res2b = f2(np.arange(0.1, 3))
res2a = f2(np.arange(3))
assert_equal(res1a, res2a)
assert_equal(res1b, res2b)
def test_string_ticket_1892(self):
# Test vectorization over strings: issue 1892.
f = np.vectorize(lambda x: x)
s = '0123456789' * 10
assert_equal(s, f(s))
def test_cache(self):
# Ensure that vectorized func called exactly once per argument.
_calls = [0]
@vectorize
def f(x):
_calls[0] += 1
return x ** 2
f.cache = True
x = np.arange(5)
assert_array_equal(f(x), x * x)
assert_equal(_calls[0], len(x))
def test_otypes(self):
f = np.vectorize(lambda x: x)
f.otypes = 'i'
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')]))
# Tests to check if whitespaces are ignored
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)
def test_subclasses(self):
class subclass(np.ndarray):
pass
m = np.array([[1., 0., 0.],
[0., 0., 1.],
[0., 1., 0.]]).view(subclass)
v = np.array([[1., 2., 3.], [4., 5., 6.], [7., 8., 9.]]).view(subclass)
# generalized (gufunc)
matvec = np.vectorize(np.matmul, signature='(m,m),(m)->(m)')
r = matvec(m, v)
assert_equal(type(r), subclass)
assert_equal(r, [[1., 3., 2.], [4., 6., 5.], [7., 9., 8.]])
# element-wise (ufunc)
mult = np.vectorize(lambda x, y: x*y)
r = mult(m, v)
assert_equal(type(r), subclass)
assert_equal(r, m * v)
def test_name(self):
#See gh-23021
@np.vectorize
def f2(a, b):
return a + b
assert f2.__name__ == 'f2'
def test_decorator(self):
@vectorize
def addsubtract(a, b):
if a > b:
return a - b
else:
return a + b
r = addsubtract([0, 3, 6, 9], [1, 3, 5, 7])
assert_array_equal(r, [1, 6, 1, 2])
def test_docstring(self):
@vectorize
def f(x):
"""Docstring"""
return x
if sys.flags.optimize < 2:
assert f.__doc__ == "Docstring"
def test_partial(self):
def foo(x, y):
return x + y
bar = partial(foo, 3)
vbar = np.vectorize(bar)
assert vbar(1) == 4
def test_signature_otypes_decorator(self):
@vectorize(signature='(n)->(n)', otypes=['float64'])
def f(x):
return x
r = f([1, 2, 3])
assert_equal(r.dtype, np.dtype('float64'))
assert_array_equal(r, [1, 2, 3])
assert f.__name__ == 'f'
def test_bad_input(self):
with assert_raises(TypeError):
A = np.vectorize(pyfunc = 3)
def test_no_keywords(self):
with assert_raises(TypeError):
@np.vectorize("string")
def foo():
return "bar"
def test_positional_regression_9477(self):
# This supplies the first keyword argument as a positional,
# to ensure that they are still properly forwarded after the
# enhancement for #9477
f = vectorize((lambda x: x), ['float64'])
r = f([2])
assert_equal(r.dtype, np.dtype('float64'))
class TestLeaks:
class A:
iters = 20
def bound(self, *args):
return 0
@staticmethod
def unbound(*args):
return 0
@pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts")
@pytest.mark.parametrize('name, incr', [
('bound', A.iters),
('unbound', 0),
])
def test_frompyfunc_leaks(self, name, incr):
# exposed in gh-11867 as np.vectorized, but the problem stems from
# frompyfunc.
# class.attribute = np.frompyfunc(