10000 ENH: Allow ptp to take an axis tuple and keepdims · eric-wieser/numpy@e772a1a · GitHub
[go: up one dir, main page]

Skip to content

Commit e772a1a

Browse files
committed
ENH: Allow ptp to take an axis tuple and keepdims
1 parent 7bb2d5a commit e772a1a

File tree

7 files changed

+62
-27
lines changed

7 files changed

+62
-27
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: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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-classes `sum` 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):

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