codekingpro/portable-devtools
115k
1import decimal
2import math
3import operator
4import sys
5import warnings
6from fractions import Fraction
7from functools import partial
8
9import hypothesis
10import hypothesis.strategies as st
11import pytest
12from hypothesis.extra.numpy import arrays
13
14import numpy as np
15import numpy.lib._function_base_impl as nfb
16from numpy import (
17 angle,
18 average,
19 bartlett,
20 blackman,
21 corrcoef,
22 cov,
23 delete,
24 diff,
25 digitize,
26 extract,
27 flipud,
28 gradient,
29 hamming,
30 hanning,
31 i0,
32 insert,
33 interp,
34 kaiser,
35 ma,
36 meshgrid,
37 piecewise,
38 place,
39 rot90,
40 select,
41 setxor1d,
42 sinc,
43 trapezoid,
44 trim_zeros,
45 unique,
46 unwrap,
47 vectorize,
48)
49from numpy._core.numeric import normalize_axis_tuple
50from numpy.exceptions import AxisError
51from numpy.random import rand
52from numpy.testing import (
53 HAS_REFCOUNT,
54 IS_WASM,
55 NOGIL_BUILD,
56 assert_,
57 assert_allclose,
58 assert_almost_equal,
59 assert_array_almost_equal,
60 assert_array_equal,
61 assert_equal,
62 assert_raises,
63 assert_raises_regex,
64)
65
66np_floats = [np.half, np.single, np.double, np.longdouble]
67
68def get_mat(n):
69 data = np.arange(n)
70 data = np.add.outer(data, data)
71 return data
72
73
74def _make_complex(real, imag):
75 """
76 Like real + 1j * imag, but behaves as expected when imag contains non-finite
77 values
78 """
79 ret = np.zeros(np.broadcast(real, imag).shape, np.complex128)
80 ret.real = real
81 ret.imag = imag
82 return ret
83
84
85class TestRot90:
86 def test_basic(self):
87 assert_raises(ValueError, rot90, np.ones(4))
88 assert_raises(ValueError, rot90, np.ones((2, 2, 2)), axes=(0, 1, 2))
89 assert_raises(ValueError, rot90, np.ones((2, 2)), axes=(0, 2))
90 assert_raises(ValueError, rot90, np.ones((2, 2)), axes=(1, 1))
91 assert_raises(ValueError, rot90, np.ones((2, 2, 2)), axes=(-2, 1))
92
93 a = [[0, 1, 2],
94 [3, 4, 5]]
95 b1 = [[2, 5],
96 [1, 4],
97 [0, 3]]
98 b2 = [[5, 4, 3],
99 [2, 1, 0]]
100 b3 = [[3, 0],
101 [4, 1],
102 [5, 2]]
103 b4 = [[0, 1, 2],
104 [3, 4, 5]]
105
106 for k in range(-3, 13, 4):
107 assert_equal(rot90(a, k=k), b1)
108 for k in range(-2, 13, 4):
109 assert_equal(rot90(a, k=k), b2)
110 for k in range(-1, 13, 4):
111 assert_equal(rot90(a, k=k), b3)
112 for k in range(0, 13, 4):
113 assert_equal(rot90(a, k=k), b4)
114
115 assert_equal(rot90(rot90(a, axes=(0, 1)), axes=(1, 0)), a)
116 assert_equal(rot90(a, k=1, axes=(1, 0)), rot90(a, k=-1, axes=(0, 1)))
117
118 def test_axes(self):
119 a = np.ones((50, 40, 3))
120 assert_equal(rot90(a).shape, (40, 50, 3))
121 assert_equal(rot90(a, axes=(0, 2)), rot90(a, axes=(0, -1)))
122 assert_equal(rot90(a, axes=(1, 2)), rot90(a, axes=(-2, -1)))
123
124 def test_rotation_axes(self):
125 a = np.arange(8).reshape((2, 2, 2))
126
127 a_rot90_01 = [[[2, 3],
128 [6, 7]],
129 [[0, 1],
130 [4, 5]]]
131 a_rot90_12 = [[[1, 3],
132 [0, 2]],
133 [[5, 7],
134 [4, 6]]]
135 a_rot90_20 = [[[4, 0],
136 [6, 2]],
137 [[5, 1],
138 [7, 3]]]
139 a_rot90_10 = [[[4, 5],
140 [0, 1]],
141 [[6, 7],
142 [2, 3]]]
143
144 assert_equal(rot90(a, axes=(0, 1)), a_rot90_01)
145 assert_equal(rot90(a, axes=(1, 0)), a_rot90_10)
146 assert_equal(rot90(a, axes=(1, 2)), a_rot90_12)
147
148 for k in range(1, 5):
149 assert_equal(rot90(a, k=k, axes=(2, 0)),
150 rot90(a_rot90_20, k=k - 1, axes=(2, 0)))
151
152
153class TestFlip:
154
155 def test_axes(self):
156 assert_raises(AxisError, np.flip, np.ones(4), axis=1)
157 assert_raises(AxisError, np.flip, np.ones((4, 4)), axis=2)
158 assert_raises(AxisError, np.flip, np.ones((4, 4)), axis=-3)
159 assert_raises(AxisError, np.flip, np.ones((4, 4)), axis=(0, 3))
160
161 def test_basic_lr(self):
162 a = get_mat(4)
163 b = a[:, ::-1]
164 assert_equal(np.flip(a, 1), b)
165 a = [[0, 1, 2],
166 [3, 4, 5]]
167 b = [[2, 1, 0],
168 [5, 4, 3]]
169 assert_equal(np.flip(a, 1), b)
170
171 def test_basic_ud(self):
172 a = get_mat(4)
173 b = a[::-1, :]
174 assert_equal(np.flip(a, 0), b)
175 a = [[0, 1, 2],
176 [3, 4, 5]]
177 b = [[3, 4, 5],
178 [0, 1, 2]]
179 assert_equal(np.flip(a, 0), b)
180
181 def test_3d_swap_axis0(self):
182 a = np.array([[[0, 1],
183 [2, 3]],
184 [[4, 5],
185 [6, 7]]])
186
187 b = np.array([[[4, 5],
188 [6, 7]],
189 [[0, 1],
190 [2, 3]]])
191
192 assert_equal(np.flip(a, 0), b)
193
194 def test_3d_swap_axis1(self):
195 a = np.array([[[0, 1],
196 [2, 3]],
197 [[4, 5],
198 [6, 7]]])
199
200 b = np.array([[[2, 3],
201 [0, 1]],
202 [[6, 7],
203 [4, 5]]])
204
205 assert_equal(np.flip(a, 1), b)
206
207 def test_3d_swap_axis2(self):
208 a = np.array([[[0, 1],
209 [2, 3]],
210 [[4, 5],
211 [6, 7]]])
212
213 b = np.array([[[1, 0],
214 [3, 2]],
215 [[5, 4],
216 [7, 6]]])
217
218 assert_equal(np.flip(a, 2), b)
219
220 def test_4d(self):
221 a = np.arange(2 * 3 * 4 * 5).reshape(2, 3, 4, 5)
222 for i in range(a.ndim):
223 assert_equal(np.flip(a, i),
224 np.flipud(a.swapaxes(0, i)).swapaxes(i, 0))
225
226 def test_default_axis(self):
227 a = np.array([[1, 2, 3],
228 [4, 5, 6]])
229 b = np.array([[6, 5, 4],
230 [3, 2, 1]])
231 assert_equal(np.flip(a), b)
232
233 def test_multiple_axes(self):
234 a = np.array([[[0, 1],
235 [2, 3]],
236 [[4, 5],
237 [6, 7]]])
238
239 assert_equal(np.flip(a, axis=()), a)
240
241 b = np.array([[[5, 4],
242 [7, 6]],
243 [[1, 0],
244 [3, 2]]])
245
246 assert_equal(np.flip(a, axis=(0, 2)), b)
247
248 c = np.array([[[3, 2],
249 [1, 0]],
250 [[7, 6],
251 [5, 4]]])
252
253 assert_equal(np.flip(a, axis=(1, 2)), c)
254
255
256class TestAny:
257
258 def test_basic(self):
259 y1 = [0, 0, 1, 0]
260 y2 = [0, 0, 0, 0]
261 y3 = [1, 0, 1, 0]
262 assert_(np.any(y1))
263 assert_(np.any(y3))
264 assert_(not np.any(y2))
265
266 def test_nd(self):
267 y1 = [[0, 0, 0], [0, 1, 0], [1, 1, 0]]
268 assert_(np.any(y1))
269 assert_array_equal(np.any(y1, axis=0), [1, 1, 0])
270 assert_array_equal(np.any(y1, axis=1), [0, 1, 1])
271
272
273class TestAll:
274
275 def test_basic(self):
276 y1 = [0, 1, 1, 0]
277 y2 = [0, 0, 0, 0]
278 y3 = [1, 1, 1, 1]
279 assert_(not np.all(y1))
280 assert_(np.all(y3))
281 assert_(not np.all(y2))
282 assert_(np.all(~np.array(y2)))
283
284 def test_nd(self):
285 y1 = [[0, 0, 1], [0, 1, 1], [1, 1, 1]]
286 assert_(not np.all(y1))
287 assert_array_equal(np.all(y1, axis=0), [0, 0, 1])
288 assert_array_equal(np.all(y1, axis=1), [0, 0, 1])
289
290
291@pytest.mark.parametrize("dtype", ["i8", "U10", "object", "datetime64[ms]"])
292def test_any_and_all_result_dtype(dtype):
293 arr = np.ones(3, dtype=dtype)
294 assert np.any(arr).dtype == np.bool
295 assert np.all(arr).dtype == np.bool
296
297
298class TestCopy:
299
300 def test_basic(self):
301 a = np.array([[1, 2], [3, 4]])
302 a_copy = np.copy(a)
303 assert_array_equal(a, a_copy)
304 a_copy[0, 0] = 10
305 assert_equal(a[0, 0], 1)
306 assert_equal(a_copy[0, 0], 10)
307
308 def test_order(self):
309 # It turns out that people rely on np.copy() preserving order by
310 # default; changing this broke scikit-learn:
311 # github.com/scikit-learn/scikit-learn/commit/7842748
312 a = np.array([[1, 2], [3, 4]])
313 assert_(a.flags.c_contiguous)
314 assert_(not a.flags.f_contiguous)
315 a_fort = np.array([[1, 2], [3, 4]], order="F")
316 assert_(not a_fort.flags.c_contiguous)
317 assert_(a_fort.flags.f_contiguous)
318 a_copy = np.copy(a)
319 assert_(a_copy.flags.c_contiguous)
320 assert_(not a_copy.flags.f_contiguous)
321 a_fort_copy = np.copy(a_fort)
322 assert_(not a_fort_copy.flags.c_contiguous)
323 assert_(a_fort_copy.flags.f_contiguous)
324
325 def test_subok(self):
326 mx = ma.ones(5)
327 assert_(not ma.isMaskedArray(np.copy(mx, subok=False)))
328 assert_(ma.isMaskedArray(np.copy(mx, subok=True)))
329 # Default behavior
330 assert_(not ma.isMaskedArray(np.copy(mx)))
331
332
333class TestAverage:
334
335 def test_basic(self):
336 y1 = np.array([1, 2, 3])
337 assert_(average(y1, axis=0) == 2.)
338 y2 = np.array([1., 2., 3.])
339 assert_(average(y2, axis=0) == 2.)
340 y3 = [0., 0., 0.]
341 assert_(average(y3, axis=0) == 0.)
342
343 y4 = np.ones((4, 4))
344 y4[0, 1] = 0
345 y4[1, 0] = 2
346 assert_almost_equal(y4.mean(0), average(y4, 0))
347 assert_almost_equal(y4.mean(1), average(y4, 1))
348
349 y5 = rand(5, 5)
350 assert_almost_equal(y5.mean(0), average(y5, 0))
351 assert_almost_equal(y5.mean(1), average(y5, 1))
352
353 @pytest.mark.parametrize(
354 'x, axis, expected_avg, weights, expected_wavg, expected_wsum',
355 [([1, 2, 3], None, [2.0], [3, 4, 1], [1.75], [8.0]),
356 ([[1, 2, 5], [1, 6, 11]], 0, [[1.0, 4.0, 8.0]],
357 [1, 3], [[1.0, 5.0, 9.5]], [[4, 4, 4]])],
358 )
359 def test_basic_keepdims(self, x, axis, expected_avg,
360 weights, expected_wavg, expected_wsum):
361 avg = np.average(x, axis=axis, keepdims=True)
362 assert avg.shape == np.shape(expected_avg)
363 assert_array_equal(avg, expected_avg)
364
365 wavg = np.average(x, axis=axis, weights=weights, keepdims=True)
366 assert wavg.shape == np.shape(expected_wavg)
367 assert_array_equal(wavg, expected_wavg)
368
369 wavg, wsum = np.average(x, axis=axis, weights=weights, returned=True,
370 keepdims=True)
371 assert wavg.shape == np.shape(expected_wavg)
372 assert_array_equal(wavg, expected_wavg)
373 assert wsum.shape == np.shape(expected_wsum)
374 assert_array_equal(wsum, expected_wsum)
375
376 def test_weights(self):
377 y = np.arange(10)
378 w = np.arange(10)
379 actual = average(y, weights=w)
380 desired = (np.arange(10) ** 2).sum() * 1. / np.arange(10).sum()
381 assert_almost_equal(actual, desired)
382
383 y1 = np.array([[1, 2, 3], [4, 5, 6]])
384 w0 = [1, 2]
385 actual = average(y1, weights=w0, axis=0)
386 desired = np.array([3., 4., 5.])
387 assert_almost_equal(actual, desired)
388
389 w1 = [0, 0, 1]
390 actual = average(y1, weights=w1, axis=1)
391 desired = np.array([3., 6.])
392 assert_almost_equal(actual, desired)
393
394 # weights and input have different shapes but no axis is specified
395 with pytest.raises(
396 TypeError,
397 match="Axis must be specified when shapes of a "
398 "and weights differ"):
399 average(y1, weights=w1)
400
401 # 2D Case
402 w2 = [[0, 0, 1], [0, 0, 2]]
403 desired = np.array([3., 6.])
404 assert_array_equal(average(y1, weights=w2, axis=1), desired)
405 assert_equal(average(y1, weights=w2), 5.)
406
407 y3 = rand(5).astype(np.float32)
408 w3 = rand(5).astype(np.float64)
409
410 assert_(np.average(y3, weights=w3).dtype == np.result_type(y3, w3))
411
412 # test weights with `keepdims=False` and `keepdims=True`
413 x = np.array([2, 3, 4]).reshape(3, 1)
414 w = np.array([4, 5, 6]).reshape(3, 1)
415
416 actual = np.average(x, weights=w, axis=1, keepdims=False)
417 desired = np.array([2., 3., 4.])
418 assert_array_equal(actual, desired)
419
420 actual = np.average(x, weights=w, axis=1, keepdims=True)
421 desired = np.array([[2.], [3.], [4.]])
422 assert_array_equal(actual, desired)
423
424 def test_weight_and_input_dims_different(self):
425 y = np.arange(12).reshape(2, 2, 3)
426 w = np.array([0., 0., 1., .5, .5, 0., 0., .5, .5, 1., 0., 0.])\
427 .reshape(2, 2, 3)
428
429 subw0 = w[:, :, 0]
430 actual = average(y, axis=(0, 1), weights=subw0)
431 desired = np.array([7., 8., 9.])
432 assert_almost_equal(actual, desired)
433
434 subw1 = w[1, :, :]
435 actual = average(y, axis=(1, 2), weights=subw1)
436 desired = np.array([2.25, 8.25])
437 assert_almost_equal(actual, desired)
438
439 subw2 = w[:, 0, :]
440 actual = average(y, axis=(0, 2), weights=subw2)
441 desired = np.array([4.75, 7.75])
442 assert_almost_equal(actual, desired)
443
444 # here the weights have the wrong shape for the specified axes
445 with pytest.raises(
446 ValueError,
447 match="Shape of weights must be consistent with "
448 "shape of a along specified axis"):
449 average(y, axis=(0, 1, 2), weights=subw0)
450
451 with pytest.raises(
452 ValueError,
453 match="Shape of weights must be consistent with "
454 "shape of a along specified axis"):
455 average(y, axis=(0, 1), weights=subw1)
456
457 # swapping the axes should be same as transposing weights
458 actual = average(y, axis=(1, 0), weights=subw0)
459 desired = average(y, axis=(0, 1), weights=subw0.T)
460 assert_almost_equal(actual, desired)
461
462 # if average over all axes, should have float output
463 actual = average(y, axis=(0, 1, 2), weights=w)
464 assert_(actual.ndim == 0)
465
466 def test_returned(self):
467 y = np.array([[1, 2, 3], [4, 5, 6]])
468
469 # No weights
470 avg, scl = average(y, returned=True)
471 assert_equal(scl, 6.)
472
473 avg, scl = average(y, 0, returned=True)
474 assert_array_equal(scl, np.array([2., 2., 2.]))
475
476 avg, scl = average(y, 1, returned=True)
477 assert_array_equal(scl, np.array([3., 3.]))
478
479 # With weights
480 w0 = [1, 2]
481 avg, scl = average(y, weights=w0, axis=0, returned=True)
482 assert_array_equal(scl, np.array([3., 3., 3.]))
483
484 w1 = [1, 2, 3]
485 avg, scl = average(y, weights=w1, axis=1, returned=True)
486 assert_array_equal(scl, np.array([6., 6.]))
487
488 w2 = [[0, 0, 1], [1, 2, 3]]
489 avg, scl = average(y, weights=w2, axis=1, returned=True)
490 assert_array_equal(scl, np.array([1., 6.]))
491
492 def test_subclasses(self):
493 class subclass(np.ndarray):
494 pass
495 a = np.array([[1, 2], [3, 4]]).view(subclass)
496 w = np.array([[1, 2], [3, 4]]).view(subclass)
497
498 assert_equal(type(np.average(a)), subclass)
499 assert_equal(type(np.average(a, weights=w)), subclass)
500 # Ensure a possibly returned sum of weights is correct too.
501 ra, rw = np.average(a, weights=w, returned=True)
502 assert_equal(type(ra), subclass)
503 assert_equal(type(rw), subclass)
504 # Even if it needs to be broadcast.
505 ra, rw = np.average(a, weights=w[0], axis=1, returned=True)
506 assert_equal(type(ra), subclass)
507 assert_equal(type(rw), subclass)
508
509 def test_upcasting(self):
510 typs = [('i4', 'i4', 'f8'), ('i4', 'f4', 'f8'), ('f4', 'i4', 'f8'),
511 ('f4', 'f4', 'f4'), ('f4', 'f8', 'f8')]
512 for at, wt, rt in typs:
513 a = np.array([[1, 2], [3, 4]], dtype=at)
514 w = np.array([[1, 2], [3, 4]], dtype=wt)
515 assert_equal(np.average(a, weights=w).dtype, np.dtype(rt))
516
517 def test_object_dtype(self):
518 a = np.array([decimal.Decimal(x) for x in range(10)])
519 w = np.array([decimal.Decimal(1) for _ in range(10)])
520 w /= w.sum()
521 assert_almost_equal(a.mean(0), average(a, weights=w))
522
523 def test_object_no_weights(self):
524 a = np.array([decimal.Decimal(x) for x in range(10)])
525 m = average(a)
526 assert m == decimal.Decimal('4.5')
527
528 def test_average_class_without_dtype(self):
529 # see gh-21988
530 a = np.array([Fraction(1, 5), Fraction(3, 5)])
531 assert_equal(np.average(a), Fraction(2, 5))
532
533
534class TestSelect:
535 choices = [np.array([1, 2, 3]),
536 np.array([4, 5, 6]),
537 np.array([7, 8, 9])]
538 conditions = [np.array([False, False, False]),
539 np.array([False, True, False]),
540 np.array([False, False, True])]
541
542 def _select(self, cond, values, default=0):
543 output = []
544 for m in range(len(cond)):
545 output += [V[m] for V, C in zip(values, cond) if C[m]] or [default]
546 return output
547
548 def test_basic(self):
549 choices = self.choices
550 conditions = self.conditions
551 assert_array_equal(select(conditions, choices, default=15),
552 self._select(conditions, choices, default=15))
553
554 assert_equal(len(choices), 3)
555 assert_equal(len(conditions), 3)
556
557 def test_broadcasting(self):
558 conditions = [np.array(True), np.array([False, True, False])]
559 choices = [1, np.arange(12).reshape(4, 3)]
560 assert_array_equal(select(conditions, choices), np.ones((4, 3)))
561 # default can broadcast too:
562 assert_equal(select([True], [0], default=[0]).shape, (1,))
563
564 def test_return_dtype(self):
565 assert_equal(select(self.conditions, self.choices, 1j).dtype,
566 np.complex128)
567 # But the conditions need to be stronger then the scalar default
568 # if it is scalar.
569 choices = [choice.astype(np.int8) for choice in self.choices]
570 assert_equal(select(self.conditions, choices).dtype, np.int8)
571
572 d = np.array([1, 2, 3, np.nan, 5, 7])
573 m = np.isnan(d)
574 assert_equal(select([m], [d]), [0, 0, 0, np.nan, 0, 0])
575
576 def test_non_bool_deprecation(self):
577 choices = self.choices
578 conditions = self.conditions[:]
579 conditions[0] = conditions[0].astype(np.int_)
580 assert_raises(TypeError, select, conditions, choices)
581 conditions[0] = conditions[0].astype(np.uint8)
582 assert_raises(TypeError, select, conditions, choices)
583 assert_raises(TypeError, select, conditions, choices)
584
585 def test_many_arguments(self):
586 # This used to be limited by NPY_MAXARGS == 32
587 conditions = [np.array([False])] * 100
588 choices = [np.array([1])] * 100
589 select(conditions, choices)
590
591
592class TestInsert:
593
594 def test_basic(self):
595 a = [1, 2, 3]
596 assert_equal(insert(a, 0, 1), [1, 1, 2, 3])
597 assert_equal(insert(a, 3, 1), [1, 2, 3, 1])
598 assert_equal(insert(a, [1, 1, 1], [1, 2, 3]), [1, 1, 2, 3, 2, 3])
599 assert_equal(insert(a, 1, [1, 2, 3]), [1, 1, 2, 3, 2, 3])
600 assert_equal(insert(a, [1, -1, 3], 9), [1, 9, 2, 9, 3, 9])
601 assert_equal(insert(a, slice(-1, None, -1), 9), [9, 1, 9, 2, 9, 3])
602 assert_equal(insert(a, [-1, 1, 3], [7, 8, 9]), [1, 8, 2, 7, 3, 9])
603 b = np.array([0, 1], dtype=np.float64)
604 assert_equal(insert(b, 0, b[0]), [0., 0., 1.])
605 assert_equal(insert(b, [], []), b)
606 assert_equal(insert(a, np.array([True] * 4), 9), [9, 1, 9, 2, 9, 3, 9])
607 assert_equal(insert(a, np.array([True, False, True, False]), 9),
608 [9, 1, 2, 9, 3])
609
610 def test_multidim(self):
611 a = [[1, 1, 1]]
612 r = [[2, 2, 2],
613 [1, 1, 1]]
614 assert_equal(insert(a, 0, [1]), [1, 1, 1, 1])
615 assert_equal(insert(a, 0, [2, 2, 2], axis=0), r)
616 assert_equal(insert(a, 0, 2, axis=0), r)
617 assert_equal(insert(a, 2, 2, axis=1), [[1, 1, 2, 1]])
618
619 a = np.array([[1, 1], [2, 2], [3, 3]])
620 b = np.arange(1, 4).repeat(3).reshape(3, 3)
621 c = np.concatenate(
622 (a[:, 0:1], np.arange(1, 4).repeat(3).reshape(3, 3).T,
623 a[:, 1:2]), axis=1)
624 assert_equal(insert(a, [1], [[1], [2], [3]], axis=1), b)
625 assert_equal(insert(a, [1], [1, 2, 3], axis=1), c)
626 # scalars behave differently, in this case exactly opposite:
627 assert_equal(insert(a, 1, [1, 2, 3], axis=1), b)
628 assert_equal(insert(a, 1, [[1], [2], [3]], axis=1), c)
629
630 a = np.arange(4).reshape(2, 2)
631 assert_equal(insert(a[:, :1], 1, a[:, 1], axis=1), a)
632 assert_equal(insert(a[:1, :], 1, a[1, :], axis=0), a)
633
634 # negative axis value
635 a = np.arange(24).reshape((2, 3, 4))
636 assert_equal(insert(a, 1, a[:, :, 3], axis=-1),
637 insert(a, 1, a[:, :, 3], axis=2))
638 assert_equal(insert(a, 1, a[:, 2, :], axis=-2),
639 insert(a, 1, a[:, 2, :], axis=1))
640
641 # invalid axis value
642 assert_raises(AxisError, insert, a, 1, a[:, 2, :], axis=3)
643 assert_raises(AxisError, insert, a, 1, a[:, 2, :], axis=-4)
644
645 # negative axis value
646 a = np.arange(24).reshape((2, 3, 4))
647 assert_equal(insert(a, 1, a[:, :, 3], axis=-1),
648 insert(a, 1, a[:, :, 3], axis=2))
649 assert_equal(insert(a, 1, a[:, 2, :], axis=-2),
650 insert(a, 1, a[:, 2, :], axis=1))
651
652 def test_0d(self):
653 a = np.array(1)
654 with pytest.raises(AxisError):
655 insert(a, [], 2, axis=0)
656 with pytest.raises(TypeError):
657 insert(a, [], 2, axis="nonsense")
658
659 def test_subclass(self):
660 class SubClass(np.ndarray):
661 pass
662 a = np.arange(10).view(SubClass)
663 assert_(isinstance(np.insert(a, 0, [0]), SubClass))
664 assert_(isinstance(np.insert(a, [], []), SubClass))
665 assert_(isinstance(np.insert(a, [0, 1], [1, 2]), SubClass))
666 assert_(isinstance(np.insert(a, slice(1, 2), [1, 2]), SubClass))
667 assert_(isinstance(np.insert(a, slice(1, -2, -1), []), SubClass))
668 # This is an error in the future:
669 a = np.array(1).view(SubClass)
670 assert_(isinstance(np.insert(a, 0, [0]), SubClass))
671
672 def test_index_array_copied(self):
673 x = np.array([1, 1, 1])
674 np.insert([0, 1, 2], x, [3, 4, 5])
675 assert_equal(x, np.array([1, 1, 1]))
676
677 def test_structured_array(self):
678 a = np.array([(1, 'a'), (2, 'b'), (3, 'c')],
679 dtype=[('foo', 'i'), ('bar', 'S1')])
680 val = (4, 'd')
681 b = np.insert(a, 0, val)
682 assert_array_equal(b[0], np.array(val, dtype=b.dtype))
683 val = [(4, 'd')] * 2
684 b = np.insert(a, [0, 2], val)
685 assert_array_equal(b[[0, 3]], np.array(val, dtype=b.dtype))
686
687 def test_index_floats(self):
688 with pytest.raises(IndexError):
689 np.insert([0, 1, 2], np.array([1.0, 2.0]), [10, 20])
690 with pytest.raises(IndexError):
691 np.insert([0, 1, 2], np.array([], dtype=float), [])
692
693 @pytest.mark.parametrize('idx', [4, -4])
694 def test_index_out_of_bounds(self, idx):
695 with pytest.raises(IndexError, match='out of bounds'):
696 np.insert([0, 1, 2], [idx], [3, 4])
697
698
699class TestAmax:
700
701 def test_basic(self):
702 a = [3, 4, 5, 10, -3, -5, 6.0]
703 assert_equal(np.amax(a), 10.0)
704 b = [[3, 6.0, 9.0],
705 [4, 10.0, 5.0],
706 [8, 3.0, 2.0]]
707 assert_equal(np.amax(b, axis=0), [8.0, 10.0, 9.0])
708 assert_equal(np.amax(b, axis=1), [9.0, 10.0, 8.0])
709
710
711class TestAmin:
712
713 def test_basic(self):
714 a = [3, 4, 5, 10, -3, -5, 6.0]
715 assert_equal(np.amin(a), -5.0)
716 b = [[3, 6.0, 9.0],
717 [4, 10.0, 5.0],
718 [8, 3.0, 2.0]]
719 assert_equal(np.amin(b, axis=0), [3.0, 3.0, 2.0])
720 assert_equal(np.amin(b, axis=1), [3.0, 4.0, 2.0])
721
722
723class TestPtp:
724
725 def test_basic(self):
726 a = np.array([3, 4, 5, 10, -3, -5, 6.0])
727 assert_equal(np.ptp(a, axis=0), 15.0)
728 b = np.array([[3, 6.0, 9.0],
729 [4, 10.0, 5.0],
730 [8, 3.0, 2.0]])
731 assert_equal(np.ptp(b, axis=0), [5.0, 7.0, 7.0])
732 assert_equal(np.ptp(b, axis=-1), [6.0, 6.0, 6.0])
733
734 assert_equal(np.ptp(b, axis=0, keepdims=True), [[5.0, 7.0, 7.0]])
735 assert_equal(np.ptp(b, axis=(0, 1), keepdims=True), [[8.0]])
736
737
738class TestCumsum:
739
740 @pytest.mark.parametrize("cumsum", [np.cumsum, np.cumulative_sum])
741 def test_basic(self, cumsum):
742 ba = [1, 2, 10, 11, 6, 5, 4]
743 ba2 = [[1, 2, 3, 4], [5, 6, 7, 9], [10, 3, 4, 5]]
744 for ctype in [np.int8, np.uint8, np.int16, np.uint16, np.int32,
745 np.uint32, np.float32, np.float64, np.complex64,
746 np.complex128]:
747 a = np.array(ba, ctype)
748 a2 = np.array(ba2, ctype)
749
750 tgt = np.array([1, 3, 13, 24, 30, 35, 39], ctype)
751 assert_array_equal(cumsum(a, axis=0), tgt)
752
753 tgt = np.array(
754 [[1, 2, 3, 4], [6, 8, 10, 13], [16, 11, 14, 18]], ctype)
755 assert_array_equal(cumsum(a2, axis=0), tgt)
756
757 tgt = np.array(
758 [[1, 3, 6, 10], [5, 11, 18, 27], [10, 13, 17, 22]], ctype)
759 assert_array_equal(cumsum(a2, axis=1), tgt)
760
761
762class TestProd:
763
764 def test_basic(self):
765 ba = [1, 2, 10, 11, 6, 5, 4]
766 ba2 = [[1, 2, 3, 4], [5, 6, 7, 9], [10, 3, 4, 5]]
767 for ctype in [np.int16, np.uint16, np.int32, np.uint32,
768 np.float32, np.float64, np.complex64, np.complex128]:
769 a = np.array(ba, ctype)
770 a2 = np.array(ba2, ctype)
771 if ctype in ['1', 'b']:
772 assert_raises(ArithmeticError, np.prod, a)
773 assert_raises(ArithmeticError, np.prod, a2, 1)
774 else:
775 assert_equal(a.prod(axis=0), 26400)
776 assert_array_equal(a2.prod(axis=0),
777 np.array([50, 36, 84, 180], ctype))
778 assert_array_equal(a2.prod(axis=-1),
779 np.array([24, 1890, 600], ctype))
780
781
782class TestCumprod:
783
784 @pytest.mark.parametrize("cumprod", [np.cumprod, np.cumulative_prod])
785 def test_basic(self, cumprod):
786 ba = [1, 2, 10, 11, 6, 5, 4]
787 ba2 = [[1, 2, 3, 4], [5, 6, 7, 9], [10, 3, 4, 5]]
788 for ctype in [np.int16, np.uint16, np.int32, np.uint32,
789 np.float32, np.float64, np.complex64, np.complex128]:
790 a = np.array(ba, ctype)
791 a2 = np.array(ba2, ctype)
792 if ctype in ['1', 'b']:
793 assert_raises(ArithmeticError, cumprod, a)
794 assert_raises(ArithmeticError, cumprod, a2, 1)
795 assert_raises(ArithmeticError, cumprod, a)
796 else:
797 assert_array_equal(cumprod(a, axis=-1),
798 np.array([1, 2, 20, 220,
799 1320, 6600, 26400], ctype))
800 assert_array_equal(cumprod(a2, axis=0),
801 np.array([[1, 2, 3, 4],
802 [5, 12, 21, 36],
803 [50, 36, 84, 180]], ctype))
804 assert_array_equal(cumprod(a2, axis=-1),
805 np.array([[1, 2, 6, 24],
806 [5, 30, 210, 1890],
807 [10, 30, 120, 600]], ctype))
808
809
810def test_cumulative_include_initial():
811 arr = np.arange(8).reshape((2, 2, 2))
812
813 expected = np.array([
814 [[0, 0], [0, 1], [2, 4]], [[0, 0], [4, 5], [10, 12]]
815 ])
816 assert_array_equal(
817 np.cumulative_sum(arr, axis=1, include_initial=True), expected
818 )
819
820 expected = np.array([
821 [[1, 0, 0], [1, 2, 6]], [[1, 4, 20], [1, 6, 42]]
822 ])
823 assert_array_equal(
824 np.cumulative_prod(arr, axis=2, include_initial=True), expected
825 )
826
827 out = np.zeros((3, 2), dtype=np.float64)
828 expected = np.array([[0, 0], [1, 2], [4, 6]], dtype=np.float64)
829 arr = np.arange(1, 5).reshape((2, 2))
830 np.cumulative_sum(arr, axis=0, out=out, include_initial=True)
831 assert_array_equal(out, expected)
832
833 expected = np.array([1, 2, 4])
834 assert_array_equal(
835 np.cumulative_prod(np.array([2, 2]), include_initial=True), expected
836 )
837
838
839class TestDiff:
840
841 def test_basic(self):
842 x = [1, 4, 6, 7, 12]
843 out = np.array([3, 2, 1, 5])
844 out2 = np.array([-1, -1, 4])
845 out3 = np.array([0, 5])
846 assert_array_equal(diff(x), out)
847 assert_array_equal(diff(x, n=2), out2)
848 assert_array_equal(diff(x, n=3), out3)
849
850 x = [1.1, 2.2, 3.0, -0.2, -0.1]
851 out = np.array([1.1, 0.8, -3.2, 0.1])
852 assert_almost_equal(diff(x), out)
853
854 x = [True, True, False, False]
855 out = np.array([False, True, False])
856 out2 = np.array([True, True])
857 assert_array_equal(diff(x), out)
858 assert_array_equal(diff(x, n=2), out2)
859
860 def test_axis(self):
861 x = np.zeros((10, 20, 30))
862 x[:, 1::2, :] = 1
863 exp = np.ones((10, 19, 30))
864 exp[:, 1::2, :] = -1
865 assert_array_equal(diff(x), np.zeros((10, 20, 29)))
866 assert_array_equal(diff(x, axis=-1), np.zeros((10, 20, 29)))
867 assert_array_equal(diff(x, axis=0), np.zeros((9, 20, 30)))
868 assert_array_equal(diff(x, axis=1), exp)
869 assert_array_equal(diff(x, axis=-2), exp)
870 assert_raises(AxisError, diff, x, axis=3)
871 assert_raises(AxisError, diff, x, axis=-4)
872
873 x = np.array(1.11111111111, np.float64)
874 assert_raises(ValueError, diff, x)
875
876 def test_nd(self):
877 x = 20 * rand(10, 20, 30)
878 out1 = x[:, :, 1:] - x[:, :, :-1]
879 out2 = out1[:, :, 1:] - out1[:, :, :-1]
880 out3 = x[1:, :, :] - x[:-1, :, :]
881 out4 = out3[1:, :, :] - out3[:-1, :, :]
882 assert_array_equal(diff(x), out1)
883 assert_array_equal(diff(x, n=2), out2)
884 assert_array_equal(diff(x, axis=0), out3)
885 assert_array_equal(diff(x, n=2, axis=0), out4)
886
887 def test_n(self):
888 x = list(range(3))
889 assert_raises(ValueError, diff, x, n=-1)
890 output = [diff(x, n=n) for n in range(1, 5)]
891 expected = [[1, 1], [0], [], []]
892 assert_(diff(x, n=0) is x)
893 for n, (expected_n, output_n) in enumerate(zip(expected, output), start=1):
894 assert_(type(output_n) is np.ndarray)
895 assert_array_equal(output_n, expected_n)
896 assert_equal(output_n.dtype, np.int_)
897 assert_equal(len(output_n), max(0, len(x) - n))
898
899 def test_times(self):
900 x = np.arange('1066-10-13', '1066-10-16', dtype=np.datetime64)
901 expected = [
902 np.array([1, 1], dtype='timedelta64[D]'),
903 np.array([0], dtype='timedelta64[D]'),
904 ]
905 expected.extend([np.array([], dtype='timedelta64[D]')] * 3)
906 for n, exp in enumerate(expected, start=1):
907 out = diff(x, n=n)
908 assert_array_equal(out, exp)
909 assert_equal(out.dtype, exp.dtype)
910
911 def test_subclass(self):
912 x = ma.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]],
913 mask=[[False, False], [True, False],
914 [False, True], [True, True], [False, False]])
915 out = diff(x)
916 assert_array_equal(out.data, [[1], [1], [1], [1], [1]])
917 assert_array_equal(out.mask, [[False], [True],
918 [True], [True], [False]])
919 assert_(type(out) is type(x))
920
921 out3 = diff(x, n=3)
922 assert_array_equal(out3.data, [[], [], [], [], []])
923 assert_array_equal(out3.mask, [[], [], [], [], []])
924 assert_(type(out3) is type(x))
925
926 def test_prepend(self):
927 x = np.arange(5) + 1
928 assert_array_equal(diff(x, prepend=0), np.ones(5))
929 assert_array_equal(diff(x, prepend=[0]), np.ones(5))
930 assert_array_equal(np.cumsum(np.diff(x, prepend=0)), x)
931 assert_array_equal(diff(x, prepend=[-1, 0]), np.ones(6))
932
933 x = np.arange(4).reshape(2, 2)
934 result = np.diff(x, axis=1, prepend=0)
935 expected = [[0, 1], [2, 1]]
936 assert_array_equal(result, expected)
937 result = np.diff(x, axis=1, prepend=[[0], [0]])
938 assert_array_equal(result, expected)
939
940 result = np.diff(x, axis=0, prepend=0)
941 expected = [[0, 1], [2, 2]]
942 assert_array_equal(result, expected)
943 result = np.diff(x, axis=0, prepend=[[0, 0]])
944 assert_array_equal(result, expected)
945
946 assert_raises(ValueError, np.diff, x, prepend=np.zeros((3, 3)))
947
948 assert_raises(AxisError, diff, x, prepend=0, axis=3)
949
950 def test_append(self):
951 x = np.arange(5)
952 result = diff(x, append=0)
953 expected = [1, 1, 1, 1, -4]
954 assert_array_equal(result, expected)
955 result = diff(x, append=[0])
956 assert_array_equal(result, expected)
957 result = diff(x, append=[0, 2])
958 expected = expected + [2]
959 assert_array_equal(result, expected)
960
961 x = np.arange(4).reshape(2, 2)
962 result = np.diff(x, axis=1, append=0)
963 expected = [[1, -1], [1, -3]]
964 assert_array_equal(result, expected)
965 result = np.diff(x, axis=1, append=[[0], [0]])
966 assert_array_equal(result, expected)
967
968 result = np.diff(x, axis=0, append=0)
969 expected = [[2, 2], [-2, -3]]
970 assert_array_equal(result, expected)
971 result = np.diff(x, axis=0, append=[[0, 0]])
972 assert_array_equal(result, expected)
973
974 assert_raises(ValueError, np.diff, x, append=np.zeros((3, 3)))
975
976 assert_raises(AxisError, diff, x, append=0, axis=3)
977
978
979class TestDelete:
980
981 def _create_arrays(self):
982 a = np.arange(5)
983 nd_a = np.arange(5).repeat(2).reshape(1, 5, 2)
984 return a, nd_a
985
986 def _check_inverse_of_slicing(self, indices):
987 a, nd_a = self._create_arrays()
988 a_del = delete(a, indices)
989 nd_a_del = delete(nd_a, indices, axis=1)
990 msg = f'Delete failed for obj: {indices!r}'
991 assert_array_equal(setxor1d(a_del, a[indices, ]), a,
992 err_msg=msg)
993 xor = setxor1d(nd_a_del[0, :, 0], nd_a[0, indices, 0])
994 assert_array_equal(xor, nd_a[0, :, 0], err_msg=msg)
995
996 def test_slices(self):
997 lims = [-6, -2, 0, 1, 2, 4, 5]
998 steps = [-3, -1, 1, 3]
999 for start in lims:
1000 for stop in lims:
1001 for step in steps:
1002 s = slice(start, stop, step)
1003 self._check_inverse_of_slicing(s)
1004
1005 def test_fancy(self):
1006 a, _ = self._create_arrays()
1007 self._check_inverse_of_slicing(np.array([[0, 1], [2, 1]]))
1008 with pytest.raises(IndexError):
1009 delete(a, [100])
1010 with pytest.raises(IndexError):
1011 delete(a, [-100])
1012
1013 self._check_inverse_of_slicing([0, -1, 2, 2])
1014
1015 self._check_inverse_of_slicing([True, False, False, True, False])
1016
1017 # not legal, indexing with these would change the dimension
1018 with pytest.raises(ValueError):
1019 delete(a, True)
1020 with pytest.raises(ValueError):
1021 delete(a, False)
1022
1023 # not enough items
1024 with pytest.raises(ValueError):
1025 delete(a, [False] * 4)
1026
1027 def test_single(self):
1028 self._check_inverse_of_slicing(0)
1029 self._check_inverse_of_slicing(-4)
1030
1031 def test_0d(self):
1032 a = np.array(1)
1033 with pytest.raises(AxisError):
1034 delete(a, [], axis=0)
1035 with pytest.raises(TypeError):
1036 delete(a, [], axis="nonsense")
1037
1038 def test_subclass(self):
1039 class SubClass(np.ndarray):
1040 pass
1041
1042 a_orig, _ = self._create_arrays()
1043 a = a_orig.view(SubClass)
1044 assert_(isinstance(delete(a, 0), SubClass))
1045 assert_(isinstance(delete(a, []), SubClass))
1046 assert_(isinstance(delete(a, [0, 1]), SubClass))
1047 assert_(isinstance(delete(a, slice(1, 2)), SubClass))
1048 assert_(isinstance(delete(a, slice(1, -2)), SubClass))
1049
1050 def test_array_order_preserve(self):
1051 # See gh-7113
1052 k = np.arange(10).reshape(2, 5, order='F')
1053 m = delete(k, slice(60, None), axis=1)
1054
1055 # 'k' is Fortran ordered, and 'm' should have the
1056 # same ordering as 'k' and NOT become C ordered
1057 assert_equal(m.flags.c_contiguous, k.flags.c_contiguous)
1058 assert_equal(m.flags.f_contiguous, k.flags.f_contiguous)
1059
1060 def test_index_floats(self):
1061 with pytest.raises(IndexError):
1062 np.delete([0, 1, 2], np.array([1.0, 2.0]))
1063 with pytest.raises(IndexError):
1064 np.delete([0, 1, 2], np.array([], dtype=float))
1065
1066 @pytest.mark.parametrize("indexer", [np.array([1]), [1]])
1067 def test_single_item_array(self, indexer):
1068 a, nd_a = self._create_arrays()
1069 a_del_int = delete(a, 1)
1070 a_del = delete(a, indexer)
1071 assert_equal(a_del_int, a_del)
1072
1073 nd_a_del_int = delete(nd_a, 1, axis=1)
1074 nd_a_del = delete(nd_a, np.array([1]), axis=1)
1075 assert_equal(nd_a_del_int, nd_a_del)
1076
1077 def test_single_item_array_non_int(self):
1078 # Special handling for integer arrays must not affect non-integer ones.
1079 # If `False` was cast to `0` it would delete the element:
1080 res = delete(np.ones(1), np.array([False]))
1081 assert_array_equal(res, np.ones(1))
1082
1083 # Test the more complicated (with axis) case from gh-21840
1084 x = np.ones((3, 1))
1085 false_mask = np.array([False], dtype=bool)
1086 true_mask = np.array([True], dtype=bool)
1087
1088 res = delete(x, false_mask, axis=-1)
1089 assert_array_equal(res, x)
1090 res = delete(x, true_mask, axis=-1)
1091 assert_array_equal(res, x[:, :0])
1092
1093 # Object or e.g. timedeltas should *not* be allowed
1094 with pytest.raises(IndexError):
1095 delete(np.ones(2), np.array([0], dtype=object))
1096
1097 with pytest.raises(IndexError):
1098 # timedeltas are sometimes "integral, but clearly not allowed:
1099 delete(np.ones(2), np.array([0], dtype="m8[ns]"))
1100
1101
1102class TestGradient:
1103
1104 def test_basic(self):
1105 v = [[1, 1], [3, 4]]
1106 x = np.array(v)
1107 dx = [np.array([[2., 3.], [2., 3.]]),
1108 np.array([[0., 0.], [1., 1.]])]
1109 assert_array_equal(gradient(x), dx)
1110 assert_array_equal(gradient(v), dx)
1111
1112 def test_args(self):
1113 dx = np.cumsum(np.ones(5))
1114 dx_uneven = [1., 2., 5., 9., 11.]
1115 f_2d = np.arange(25).reshape(5, 5)
1116
1117 # distances must be scalars or have size equal to gradient[axis]
1118 gradient(np.arange(5), 3.)
1119 gradient(np.arange(5), np.array(3.))
1120 gradient(np.arange(5), dx)
1121 # dy is set equal to dx because scalar
1122 gradient(f_2d, 1.5)
1123 gradient(f_2d, np.array(1.5))
1124
1125 gradient(f_2d, dx_uneven, dx_uneven)
1126 # mix between even and uneven spaces and
1127 # mix between scalar and vector
1128 gradient(f_2d, dx, 2)
1129
1130 # 2D but axis specified
1131 gradient(f_2d, dx, axis=1)
1132
1133 # 2d coordinate arguments are not yet allowed
1134 assert_raises_regex(ValueError, '.*scalars or 1d',
1135 gradient, f_2d, np.stack([dx] * 2, axis=-1), 1)
1136
1137 def test_badargs(self):
1138 f_2d = np.arange(25).reshape(5, 5)
1139 x = np.cumsum(np.ones(5))
1140
1141 # wrong sizes
1142 assert_raises(ValueError, gradient, f_2d, x, np.ones(2))
1143 assert_raises(ValueError, gradient, f_2d, 1, np.ones(2))
1144 assert_raises(ValueError, gradient, f_2d, np.ones(2), np.ones(2))
1145 # wrong number of arguments
1146 assert_raises(TypeError, gradient, f_2d, x)
1147 assert_raises(TypeError, gradient, f_2d, x, axis=(0, 1))
1148 assert_raises(TypeError, gradient, f_2d, x, x, x)
1149 assert_raises(TypeError, gradient, f_2d, 1, 1, 1)
1150 assert_raises(TypeError, gradient, f_2d, x, x, axis=1)
1151 assert_raises(TypeError, gradient, f_2d, 1, 1, axis=1)
1152
1153 def test_datetime64(self):
1154 # Make sure gradient() can handle special types like datetime64
1155 x = np.array(
1156 ['1910-08-16', '1910-08-11', '1910-08-10', '1910-08-12',
1157 '1910-10-12', '1910-12-12', '1912-12-12'],
1158 dtype='datetime64[D]')
1159 dx = np.array(
1160 [-5, -3, 0, 31, 61, 396, 731],
1161 dtype='timedelta64[D]')
1162 assert_array_equal(gradient(x), dx)
1163 assert_(dx.dtype == np.dtype('timedelta64[D]'))
1164
1165 def test_masked(self):
1166 # Make sure that gradient supports subclasses like masked arrays
1167 x = np.ma.array([[1, 1], [3, 4]],
1168 mask=[[False, False], [False, False]])
1169 out = gradient(x)[0]
1170 assert_equal(type(out), type(x))
1171 # And make sure that the output and input don't have aliased mask
1172 # arrays
1173 assert_(x._mask is not out._mask)
1174 # Also check that edge_order=2 doesn't alter the original mask
1175 x2 = np.ma.arange(5)
1176 x2[2] = np.ma.masked
1177 np.gradient(x2, edge_order=2)
1178 assert_array_equal(x2.mask, [False, False, True, False, False])
1179
1180 def test_second_order_accurate(self):
1181 # Testing that the relative numerical error is less that 3% for
1182 # this example problem. This corresponds to second order
1183 # accurate finite differences for all interior and boundary
1184 # points.
1185 x = np.linspace(0, 1, 10)
1186 dx = x[1] - x[0]
1187 y = 2 * x ** 3 + 4 * x ** 2 + 2 * x
1188 analytical = 6 * x ** 2 + 8 * x + 2
1189 num_error = np.abs((np.gradient(y, dx, edge_order=2) / analytical) - 1)
1190 assert_(np.all(num_error < 0.03) == True)
1191
1192 # test with unevenly spaced
1193 rng = np.random.default_rng(0)
1194 x = np.sort(rng.random(10))
1195 y = 2 * x ** 3 + 4 * x ** 2 + 2 * x
1196 analytical = 6 * x ** 2 + 8 * x + 2
1197 num_error = np.abs((np.gradient(y, x, edge_order=2) / analytical) - 1)
1198 assert_(np.all(num_error < 0.03) == True)
1199
1200 def test_spacing(self):
