Repository: numpy/numpy

Issue:
numpy.ma.compress fails because of the argument order (Trac #1902)
_Original ticket http://projects.scipy.org/numpy/ticket/1902 on 2011-07-11 by @efiring, assigned to @pierregm._

The _frommethod class used to make ma.compress assumes the first argument is the object on which the function is acting, but the compress signature is compress(cond, arr). Example of the resulting failure:

```
In [14]: arr = np.arange(8)

In [15]: arr.shape = 4,2

In [16]: cond = np.array([True, False, True, True])

In [17]: np.ma.compress(cond, arr, axis=0)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/home/efiring/<ipython-input-17-50a13b754f15> in <module>()
----> 1 np.ma.compress(cond, arr, axis=0)

/usr/local/lib/python2.7/dist-packages/numpy/ma/core.pyc in __call__(self, a, *args, **params)
   5931         method = getattr(a, method_name, None)
   5932         if method is not None:
-> 5933             return method(*args, **params)
   5934         # Still here ? Then a is not a MaskedArray

   5935         method = getattr(MaskedArray, method_name, None)

ValueError: condition must be 1-d array
```



Discussion:

Resolving patch:
diff --git a/numpy/ma/core.py b/numpy/ma/core.py
--- a/numpy/ma/core.py
+++ b/numpy/ma/core.py
@@ -5975,9 +5975,10 @@ class _frommethod:
         Name of the method to transform.
 
     """
-    def __init__(self, methodname):
+    def __init__(self, methodname, reversed=False):
         self.__name__ = methodname
         self.__doc__ = self.getdoc()
+        self.reversed = reversed
     #
     def getdoc(self):
         "Return the doc of the function (from the doc of the method)."
@@ -5989,6 +5990,11 @@ def getdoc(self):
             return doc
     #
     def __call__(self, a, *args, **params):
+        if self.reversed:
+            args = list(args)
+            arr = args[0]
+            args[0] = a
+            a = arr
         # Get the method from the array (if possible)
         method_name = self.__name__
         method = getattr(a, method_name, None)
@@ -6005,7 +6011,7 @@ def __call__(self, a, *args, **params):
 all = _frommethod('all')
 anomalies = anom = _frommethod('anom')
 any = _frommethod('any')
-compress = _frommethod('compress')
+compress = _frommethod('compress', reversed=True)
 cumprod = _frommethod('cumprod')
 cumsum = _frommethod('cumsum')
 copy = _frommethod('copy')


Test patch:
diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py
--- a/numpy/ma/tests/test_core.py
+++ b/numpy/ma/tests/test_core.py
@@ -3381,6 +3381,19 @@ def test_on_ndarray(self):
         test = reshape(a, (2, 2))
         assert_equal(test, m.reshape(2, 2))
 
+    def test_compress(self):
+        # Test compress function on ndarray and masked array
+        # Address Github #2495.
+        arr = np.arange(8)
+        arr.shape = 4,2
+        cond = np.array([True, False, True, True])
+        control = arr[[0, 2, 3]]
+        test = np.ma.compress(cond, arr, axis=0)
+        assert_equal(test, control)
+        marr = np.ma.array(arr)
+        test = np.ma.compress(cond, marr, axis=0)
+        assert_equal(test, control)
+
 #------------------------------------------------------------------------------
 
 class TestMaskedFields(TestCase):