Repository: pandas-dev/pandas

Issue:
COMPAT: comparisons with as_recarray breaking on older numpies
https://travis-ci.org/pydata/pandas/jobs/135897420

cc @gfyoung 



Discussion:
xref #13373 

Nitpick: can we change the title, as AFAICT that machine is using `1.7.1`

Arghh...there's a bug in `np.array_equal` from that version (`1.7.1`) in which it cannot compare `recarray`, so I can't check the correctness of `as_recarray` (which returns a `recarray`) in that test using `tm.assert_numpy_array_equal`.

@jreback : How to proceed?

oh, you can put in a path if its a recarry, just maybe assert that both sides are recarray and listify (and assert_almost_equal)? (e.g. that will minimize impact on other code)

Hmm...well it isn't actually `numpy.recarray` that's the issue.  Rather, it's `numpy` arrays like this:

``` python
>>> m
array([(1, 2.0), (3, 4.0)], 
      dtype=[('a', '<i8'), ('b', '<f8')])
>>> np.array_equal(m, m)  # should return True
NotImplemented
```

Might need to do `try-except` with specific checking of the error message.


Resolving patch:
diff --git a/pandas/core/common.py b/pandas/core/common.py
--- a/pandas/core/common.py
+++ b/pandas/core/common.py
@@ -349,7 +349,24 @@ def array_equivalent(left, right, strict_nan=False):
         right = right.view('i8')
 
     # NaNs cannot occur otherwise.
-    return np.array_equal(left, right)
+    try:
+        return np.array_equal(left, right)
+    except AttributeError:
+        # see gh-13388
+        #
+        # NumPy v1.7.1 has a bug in its array_equal
+        # function that prevents it from correctly
+        # comparing two arrays with complex dtypes.
+        # This bug is corrected in v1.8.0, so remove
+        # this try-except block as soon as we stop
+        # supporting NumPy versions < 1.8.0
+        if not is_dtype_equal(left.dtype, right.dtype):
+            return False
+
+        left = left.tolist()
+        right = right.tolist()
+
+        return left == right
 
 
 def _iterable_not_string(x):


Test patch:
diff --git a/pandas/tests/test_common.py b/pandas/tests/test_common.py
--- a/pandas/tests/test_common.py
+++ b/pandas/tests/test_common.py
@@ -832,6 +832,24 @@ def test_is_timedelta():
     assert (not com.is_timedelta64_ns_dtype(tdi.astype('timedelta64[h]')))
 
 
+def test_array_equivalent_compat():
+    # see gh-13388
+    m = np.array([(1, 2), (3, 4)], dtype=[('a', int), ('b', float)])
+    n = np.array([(1, 2), (3, 4)], dtype=[('a', int), ('b', float)])
+    assert (com.array_equivalent(m, n, strict_nan=True))
+    assert (com.array_equivalent(m, n, strict_nan=False))
+
+    m = np.array([(1, 2), (3, 4)], dtype=[('a', int), ('b', float)])
+    n = np.array([(1, 2), (4, 3)], dtype=[('a', int), ('b', float)])
+    assert (not com.array_equivalent(m, n, strict_nan=True))
+    assert (not com.array_equivalent(m, n, strict_nan=False))
+
+    m = np.array([(1, 2), (3, 4)], dtype=[('a', int), ('b', float)])
+    n = np.array([(1, 2), (3, 4)], dtype=[('b', int), ('a', float)])
+    assert (not com.array_equivalent(m, n, strict_nan=True))
+    assert (not com.array_equivalent(m, n, strict_nan=False))
+
+
 if __name__ == '__main__':
     nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'],
                    exit=False)