8000 Merge pull request #10287 from eric-wieser/ptp-empty · eric-wieser/numpy@e06d361 · GitHub
[go: up one dir, main page]

Skip to content

Commit e06d361

Browse files
authored
Merge pull request numpy#10287 from eric-wieser/ptp-empty
ENH: Allow ptp to take an axis tuple and keepdims
2 parents 47cbd40 + ce3d40e commit e06d361

File tree

7 files changed

+71
-36
lines changed

7 files changed

+71
-36
lines changed

doc/release/1.15.0-notes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ passed explicitly, and are not yet computed automatically.
8585
though they are arrays of length 1. Previously, passing these was an error.
8686
As a result, ``np.ma.mr_`` now works correctly on the ``masked`` constant.
8787

88+
``np.ptp`` accepts a ``keepdims`` argument, and extended axis tuples
89+
--------------------------------------------------------------------
90+
``np.ptp`` (peak-to-peak) can now work over multiple axes, just like `max` and
91+
`min`.
92+
8893
``MaskedArray.astype`` now is identical to ``ndarray.astype``
8994
-------------------------------------------------------------
9095
This means it takes all the same arguments, making more code written for

numpy/add_newdocs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4055,7 +4055,7 @@ def luf(lamdaexpr, *args, **kwargs):
40554055

40564056
add_newdoc('numpy.core.multiarray', 'ndarray', ('ptp',
40574057
"""
4058-
a.ptp(axis=None, out=None)
4058+
a.ptp(axis=None, out=None, keepdims=False)
40594059
40604060
Peak to peak (maximum - minimum) value along a given axis.
40614061

numpy/core/_methods.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,10 @@ def _std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False):
142142
ret = um.sqrt(ret)
143143

144144
return ret
145+
146+
def _ptp(a, axis=None, out=None, keepdims=False):
147+
return um.subtract(
148+
umr_maximum(a, axis, None, out, keepdims),
149+
umr_minimum(a, axis, None, None, keepdims),
150+
out
151+
)

numpy/core/fromnumeric.py

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1812,7 +1812,7 @@ def sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue):
18121812
If the default value is passed, then `keepdims` will not be
18131813
passed through to the `sum` method of sub-classes of
18141814
`ndarray`, however any non-default value will be. If the
1815-
sub-classes `sum` method does not implement `keepdims` any
1815+
sub-class' method does not implement `keepdims` any
18161816
exceptions will be raised.
18171817
18181818
Returns
@@ -1966,7 +1966,7 @@ def any(a, axis=None, out=None, keepdims=np._NoValue):
19661966
If the default value is passed, then `keepdims` will not be
19671967
passed through to the `any` method of sub-classes of
19681968
`ndarray`, however any non-default value will be. If the
1969-
sub-classes `sum` method does not implement `keepdims` any
1969+
sub-class' method does not implement `keepdims` any
19701970
exceptions will be raised.
19711971
19721972
Returns
@@ -2051,7 +2051,7 @@ def all(a, axis=None, out=None, keepdims=np._NoValue):
20512051
If the default value is passed, then `keepdims` will not be
20522052
passed through to the `all` method of sub-classes of
20532053
`ndarray`, however any non-default value will be. If the
2054-
sub-classes `sum` method does not implement `keepdims` any
2054+
sub-class' method does not implement `keepdims` any
20552055
exceptions will be raised.
20562056
20572057
Returns
@@ -2178,7 +2178,7 @@ def cumproduct(a, axis=None, dtype=None, out=None):
21782178
return _wrapfunc(a, 'cumprod', axis=axis, dtype=dtype, out=out)
21792179

21802180

2181-
def ptp(a, axis=None, out=None):
2181+
def ptp(a, axis=None, out=None, keepdims=np._NoValue):
21822182
"""
21832183
Range of values (maximum - minimum) along an axis.
21842184
@@ -2188,14 +2188,31 @@ def ptp(a, axis=None, out=None):
21882188
----------
21892189
a : array_like
21902190
Input values.
2191-
axis : int, optional
2191+
axis : None or int or tuple of ints, optional
21922192
Axis along which to find the peaks. By default, flatten the
2193-
array.
2193+
array. `axis` may be negative, in
2194+
which case it counts from the last to the first axis.
2195+
2196+
.. versionadded:: 1.15.0
2197+
2198+
If this is a tuple of ints, a reduction is performed on multiple
2199+
axes, instead of a single axis or all the axes as before.
21942200
out : array_like
21952201
Alternative output array in which to place the result. It must
21962202
have the same shape and buffer length as the expected output,
21972203
but the type of the output values will be cast if necessary.
21982204
2205+
keepdims : bool, optional
2206+
If this is set to True, the axes which are reduced are left
2207+
in the result as dimensions with size one. With this option,
2208+
the result will broadcast correctly against the input array.
2209+
2210+
If the default value is passed, then `keepdims` will not be
2211+
passed through to the `ptp` method of sub-classes of
2212+
`ndarray`, however any non-default value will be. If the
2213+
sub-class' method does not implement `keepdims` any
2214+
exceptions will be raised.
2215+
21992216
Returns
22002217
-------
22012218
ptp : ndarray
@@ -2216,7 +2233,17 @@ def ptp(a, axis=None, out=None):
22162233
array([1, 1])
22172234
22182235
"""
2219-
return _wrapfunc(a, 'ptp', axis=axis, out=out)
2236+
kwargs = {}
2237+
if keepdims is not np._NoValue:
2238+
kwargs['keepdims'] = keepdims
2239+
if type(a) is not mu.ndarray:
2240+
try:
2241+
ptp = a.ptp
2242+
except AttributeError:
2243+
pass
2244+
else:
2245+
return ptp(axis=axis, out=out, **kwargs)
2246+
return _methods._ptp(a, axis=axis, out=out, **kwargs)
22202247

22212248

22222249
def amax(a, axis=None, out=None, keepdims=np._NoValue):
@@ -2248,7 +2275,7 @@ def amax(a, axis=None, out=None, keepdims=np._NoValue):
22482275
If the default value is passed, then `keepdims` will not be
22492276
passed through to the `amax` method of sub-classes of
22502277
`ndarray`, however any non-default value will be. If the
2251-
sub-classes `sum` method does not implement `keepdims` any
2278+
sub-class' method does not implement `keepdims` any
22522279
exceptions will be raised.
22532280
22542281
Returns
@@ -2349,7 +2376,7 @@ def amin(a, axis=None, out=None, keepdims=np._NoValue):
23492376
If the default value is passed, then `keepdims` will not be
23502377
passed through to the `amin` method of sub-classes of
23512378
`ndarray`, however any non-default value will be. If the
2352-
sub-classes `sum` method does not implement `keepdims` any
2379+
sub-class' method does not implement `keepdims` any
23532380
exceptions will be raised.
23542381
23552382
Returns
@@ -2491,7 +2518,7 @@ def prod(a, axis=None, dtype=None, out=None, keepdims=np._NoValue):
24912518
If the default value is passed, then `keepdims` will not be
24922519
passed through to the `prod` method of sub-classes of
24932520
`ndarray`, however any non-default value will be. If the
2494-
sub-classes `sum` method does not implement `keepdims` any
2521+
sub-class' method does not implement `keepdims` any
24952522
exceptions will be raised.
24962523
24972524
Returns
@@ -2890,7 +2917,7 @@ def mean(a, axis=None, dtype=None, out=None, keepdims=np._NoValue):
28902917
If the default value is passed, then `keepdims` will not be
28912918
passed through to the `mean` method of sub-classes of
28922919
`ndarray`, however any non-default value will be. If the
2893-
sub-classes `sum` method does not implement `keepdims` any
2920+
sub-class' method does not implement `keepdims` any
28942921
exceptions will be raised.
28952922
28962923
Returns
@@ -2997,7 +3024,7 @@ def std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue):
29973024
If the default value is passed, then `keepdims` will not be
29983025
passed through to the `std` method of sub-classes of
29993026
`ndarray`, however any non-default value will be. If the
3000-
sub-classes `sum` method does not implement `keepdims` any
3027+
sub-class' method does not implement `keepdims` any
30013028
exceptions will be raised.
30023029
30033030
Returns
@@ -3116,7 +3143,7 @@ def var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue):
31163143
If the default value is passed, then `keepdims` will not be
31173144
passed through to the `var` method of sub-classes of
31183145
`ndarray`, however any non-default value will be. If the
3119-
sub-classes `sum` method does not implement `keepdims` any
3146+
sub-class' method does not implement `keepdims` any
31203147
exceptions will be raised.
31213148
31223149
Returns

numpy/core/src/multiarray/methods.c

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -329,16 +329,7 @@ array_min(PyArrayObject *self, PyObject *args, PyObject *kwds)
329329
static PyObject *
330330
array_ptp(PyArrayObject *self, PyObject *args, PyObject *kwds)
331331
{
332-
int axis = NPY_MAXDIMS;
333-
PyArrayObject *out = NULL;
334-
static char *kwlist[] = {"axis", "out", NULL};
335-
336-
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&O&:ptp", kwlist,
337-
PyArray_AxisConverter, &axis,
338-
PyArray_OutputConverter, &out))
339-
return NULL;
340-
341-
return PyArray_Ptp(self, axis, out);
332+
NPY_FORWARD_NDARRAY_METHOD("_ptp");
342333
}
343334

344335

numpy/lib/tests/test_function_base.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,9 @@ def test_basic(self):
556556
assert_equal(b.ptp(axis=0), [5.0, 7.0, 7.0])
557557
assert_equal(b.ptp(axis=-1), [6.0, 6.0, 6.0])
558558

559+
assert_equal(b.ptp(axis=0, keepdims=True), [[5.0, 7.0, 7.0]])
560+
assert_equal(b.ptp(axis=(0,1), keepdims=True), [[8.0]])
561+
559562

560563
class TestCumsum(object):
561564

numpy/ma/core.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5721,7 +5721,7 @@ def max(self, axis=None, out=None, fill_value=None, keepdims=np._NoValue):
57215721
np.copyto(out, np.nan, where=newmask)
57225722
return out
57235723

5724-
def ptp(self, axis=None, out=None, fill_value=None):
5724+
def ptp(self, axis=None, out=None, fill_value=None, keepdims=False):
57255725
"""
57265726
Return (maximum - minimum) along the given dimension
57275727
(i.e. peak-to-peak value).
@@ -5746,11 +5746,15 @@ def ptp(self, axis=None, out=None, fill_value=None):
57465746
57475747
"""
57485748
if out is None:
5749-
result = self.max(axis=axis, fill_value=fill_value)
5750-
result -= self.min(axis=axis, fill_value=fill_value)
5749+
result = self.max(axis=axis, fill_value=fill_value,
5750+
keepdims=keepdims)
5751+
result -= self.min(axis=axis, fill_value=fill_value,
5752+
keepdims=keepdims)
57515753
return result
5752-
out.flat = self.max(axis=axis, out=out, fill_value=fill_value)
5753-
min_value = self.min(axis=axis, fill_value=fill_value)
5754+
out.flat = self.max(axis=axis, out=out, fill_value=fill_value,
5755+
keepdims=keepdims)
5756+
min_value = self.min(axis=axis, fill_value=fill_value,
5757+
keepdims=keepdims)
57545758
np.subtract(out, min_value, out=out, casting='unsafe')
57555759
return out
57565760

@@ -6489,17 +6493,15 @@ def max(obj, axis=None, out=None, fill_value=None, keepdims=np._NoValue):
64896493
max.__doc__ = MaskedArray.max.__doc__
64906494

64916495

6492-
def ptp(obj, axis=None, out=None, fill_value=None):
6493-
"""
6494-
a.ptp(axis=None) = a.max(axis) - a.min(axis)
6495-
6496-
"""
6496+
def ptp(obj, axis=None, out=None, fill_value=None, keepdims=np._NoValue):
6497+
kwargs = {} if keepdims is np._NoValue else {'keepdims': keepdims}
64976498
try:
6498-
return obj.ptp(axis, out=out, fill_value=fill_value)
6499+
return obj.ptp(axis, out=out, fill_value=fill_value, **kwargs)
64996500
except (AttributeError, TypeError):
65006501
# If obj doesn't have a ptp method or if the method doesn't accept
65016502
# a fill_value argument
6502-
return asanyarray(obj).ptp(axis=axis, fill_value=fill_value, out=out)
6503+
return asanyarray(obj).ptp(axis=axis, fill_value=fill_value,
6504+
out=out, **kwargs)
65036505
ptp.__doc__ = MaskedArray.ptp.__doc__
65046506

65056507

0 commit comments

Comments
 (0)
0