Repository: numpy/numpy

Issue:
Documentation of ndarray.clip is misleading (Trac #1745)
_Original ticket http://projects.scipy.org/numpy/ticket/1745 on 2011-02-17 by @fengy-research, assigned to unknown._

clip doesn't accept a_min and a_max as keyword arguments.



Discussion:
_@rgommers wrote on 2011-03-29_

This is a bug, not a documentation issue. Positional arguments should be usable as keyword arguments.

Milestone changed to `Unscheduled` by @rgommers on 2011-03-29

_@bsouthey wrote on 2011-04-29_

Since this came from scipy ticket 1414. The numpy.clip function does have these keywords but not the method called by the array.

```
Python 2.5.5 (r255:77872, Nov  8 2010, 09:10:42)
[GCC 4.5.1 20100924 (Red Hat 4.5.1-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> np.__version__
'1.5.1'
>>> a=np.arange(-10,10, dtype=float)
>>> a.clip(a_min=0, a_max=10)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'a_max' is an invalid keyword argument for this function
>>> a.clip(min=0, max=10)
 array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  2., 3.,  4.,  5.,  6.,  7.,  8., 9.])                             
>>> np.clip(a,a_min=0, a_max=np.inf)
array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  2.,
       3.,  4.,  5.,  6.,  7.,  8.,  9.])
```

_@rgommers wrote on 2011-04-29_

The method has "min" and "max" positional args (which can also be keyword args, while the function has "a_min" and "a_max". This is odd, for consistency I propose to change the function args to min/max.

_@charris wrote on 2011-04-30_

+1 for this change. Because it will require a deprecation, I suggest that the positions be interchanged, i.e., the arguments in the order a, min, max, a_min, a_max. Since the functionality won't change between min/a_min, max/a_max this shouldn't cause any problems.

_@rgommers wrote on 2011-04-30_

Not sure I follow you there. The signatures are

```
a.clip(min, max)
np.clip(a, a_min, a_max)
```

so there is nothing to interchange. For the method the doc needs fixing, for the function the arguments need to be renamed. Although now that I think of it, maybe this was done on purpose because the function is written in Python and could clash with the builtins min/max. The method is written in C and therefore doesn't have this issue.


Resolving patch:
diff --git a/numpy/add_newdocs.py b/numpy/add_newdocs.py
--- a/numpy/add_newdocs.py
+++ b/numpy/add_newdocs.py
@@ -2982,7 +2982,7 @@ def luf(lamdaexpr, *args, **kwargs):
 
 add_newdoc('numpy.core.multiarray', 'ndarray', ('all',
     """
-    a.all(axis=None, out=None)
+    a.all(axis=None, out=None, keepdims=False)
 
     Returns True if all elements evaluate to True.
 
@@ -2997,7 +2997,7 @@ def luf(lamdaexpr, *args, **kwargs):
 
 add_newdoc('numpy.core.multiarray', 'ndarray', ('any',
     """
-    a.any(axis=None, out=None)
+    a.any(axis=None, out=None, keepdims=False)
 
     Returns True if any of the elements of `a` evaluate to True.
 
@@ -3198,9 +3198,10 @@ def luf(lamdaexpr, *args, **kwargs):
 
 add_newdoc('numpy.core.multiarray', 'ndarray', ('clip',
     """
-    a.clip(a_min, a_max, out=None)
+    a.clip(min=None, max=None, out=None)
 
-    Return an array whose values are limited to ``[a_min, a_max]``.
+    Return an array whose values are limited to ``[min, max]``.
+    One of max or min must be given.
 
     Refer to `numpy.clip` for full documentation.
 
@@ -3656,7 +3657,7 @@ def luf(lamdaexpr, *args, **kwargs):
 
 add_newdoc('numpy.core.multiarray', 'ndarray', ('mean',
     """
-    a.mean(axis=None, dtype=None, out=None)
+    a.mean(axis=None, dtype=None, out=None, keepdims=False)
 
     Returns the average of the array elements along given axis.
 
@@ -3671,7 +3672,7 @@ def luf(lamdaexpr, *args, **kwargs):
 
 add_newdoc('numpy.core.multiarray', 'ndarray', ('min',
     """
-    a.min(axis=None, out=None)
+    a.min(axis=None, out=None, keepdims=False)
 
     Return the minimum along a given axis.
 
@@ -3769,7 +3770,7 @@ def luf(lamdaexpr, *args, **kwargs):
 
 add_newdoc('numpy.core.multiarray', 'ndarray', ('prod',
     """
-    a.prod(axis=None, dtype=None, out=None)
+    a.prod(axis=None, dtype=None, out=None, keepdims=False)
 
     Return the product of the array elements over the given axis
 
@@ -4300,7 +4301,7 @@ def luf(lamdaexpr, *args, **kwargs):
 
 add_newdoc('numpy.core.multiarray', 'ndarray', ('std',
     """
-    a.std(axis=None, dtype=None, out=None, ddof=0)
+    a.std(axis=None, dtype=None, out=None, ddof=0, keepdims=False)
 
     Returns the standard deviation of the array elements along given axis.
 
@@ -4315,7 +4316,7 @@ def luf(lamdaexpr, *args, **kwargs):
 
 add_newdoc('numpy.core.multiarray', 'ndarray', ('sum',
     """
-    a.sum(axis=None, dtype=None, out=None)
+    a.sum(axis=None, dtype=None, out=None, keepdims=False)
 
     Return the sum of the array elements over the given axis.
 
@@ -4547,7 +4548,7 @@ def luf(lamdaexpr, *args, **kwargs):
 
 add_newdoc('numpy.core.multiarray', 'ndarray', ('var',
     """
-    a.var(axis=None, dtype=None, out=None, ddof=0)
+    a.var(axis=None, dtype=None, out=None, ddof=0, keepdims=False)
 
     Returns the variance of the array elements, along given axis.
 
diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py
--- a/numpy/core/fromnumeric.py
+++ b/numpy/core/fromnumeric.py
@@ -900,7 +900,7 @@ def argsort(a, axis=-1, kind='quicksort', order=None):
     return argsort(axis, kind, order)
 
 
-def argmax(a, axis=None):
+def argmax(a, axis=None, out=None):
     """
     Returns the indices of the maximum values along an axis.
 
@@ -911,6 +911,9 @@ def argmax(a, axis=None):
     axis : int, optional
         By default, the index is into the flattened array, otherwise
         along the specified axis.
+    out : array, optional
+        If provided, the result will be inserted into this array. It should
+        be of the appropriate shape and dtype.
 
     Returns
     -------
@@ -953,11 +956,11 @@ def argmax(a, axis=None):
     try:
         argmax = a.argmax
     except AttributeError:
-        return _wrapit(a, 'argmax', axis)
-    return argmax(axis)
+        return _wrapit(a, 'argmax', axis, out)
+    return argmax(axis, out)
 
 
-def argmin(a, axis=None):
+def argmin(a, axis=None, out=None):
     """
     Returns the indices of the minimum values along an axis.
 
@@ -968,6 +971,9 @@ def argmin(a, axis=None):
     axis : int, optional
         By default, the index is into the flattened array, otherwise
         along the specified axis.
+    out : array, optional
+        If provided, the result will be inserted into this array. It should
+        be of the appropriate shape and dtype.
 
     Returns
     -------
@@ -1010,8 +1016,8 @@ def argmin(a, axis=None):
     try:
         argmin = a.argmin
     except AttributeError:
-        return _wrapit(a, 'argmin', axis)
-    return argmin(axis)
+        return _wrapit(a, 'argmin', axis, out)
+    return argmin(axis, out)
 
 
 def searchsorted(a, v, side='left', sorter=None):


Test patch:
diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py
--- a/numpy/core/tests/test_multiarray.py
+++ b/numpy/core/tests/test_multiarray.py
@@ -2638,6 +2638,22 @@ def test_argmax_unicode(self):
         d[5942] = "as"
         assert_equal(d.argmax(), 5942)
 
+    def test_np_vs_ndarray(self):
+        # make sure both ndarray.argmax and numpy.argmax support out/axis args
+        a = np.random.normal(size=(2,3))
+
+        #check positional args
+        out1 = zeros(2, dtype=int)
+        out2 = zeros(2, dtype=int)
+        assert_equal(a.argmax(1, out1), np.argmax(a, 1, out2))
+        assert_equal(out1, out2)
+
+        #check keyword args
+        out1 = zeros(3, dtype=int)
+        out2 = zeros(3, dtype=int)
+        assert_equal(a.argmax(out=out1, axis=0), np.argmax(a, out=out2, axis=0))
+        assert_equal(out1, out2)
+
 
 class TestArgmin(TestCase):
 
@@ -2748,6 +2764,22 @@ def test_argmin_unicode(self):
         d[6001] = "0"
         assert_equal(d.argmin(), 6001)
 
+    def test_np_vs_ndarray(self):
+        # make sure both ndarray.argmin and numpy.argmin support out/axis args
+        a = np.random.normal(size=(2,3))
+
+        #check positional args
+        out1 = zeros(2, dtype=int)
+        out2 = ones(2, dtype=int)
+        assert_equal(a.argmin(1, out1), np.argmin(a, 1, out2))
+        assert_equal(out1, out2)
+
+        #check keyword args
+        out1 = zeros(3, dtype=int)
+        out2 = ones(3, dtype=int)
+        assert_equal(a.argmin(out=out1, axis=0), np.argmin(a, out=out2, axis=0))
+        assert_equal(out1, out2)
+
 
 class TestMinMax(TestCase):
     def test_scalar(self):