0

I need to check if not all elements are the same in numpy array.

import numpy as np
from datetime import date

arr1 = np.array(
[np.array([date(2022,12,14)]),
np.array([date(2022,12,15)])]
)

arr2 = np.array(
[np.array([date(2022,12,14)]),
np.array([date(2022,12,19), date(2022, 12, 20), date(2022, 12, 21)])]
)

Now, arr1 != arr1[0] returns array([[False],[ True]]), and taking this into np.all() correctly returns False. However, arr2 != arr2[0] just returns True instead of expected array([[False],[ True]]). Why does it happen? Is there a quick workaround?

@edit I'm thinking of using

[np.array_equiv(arr2[0], dates) for dates in arr2]

Then I'm correctly getting [False, True] upon which I can apply np.all(), but is it the best solution for that case?

2
  • 1
    In short numpy wants to create arrays that have a shape, operations on these will have outputs of the same shape. arr1 has shape (2,1), arr2 has no shape as the objects have different lengths. Construct arrays with objects that have the same sizes. Or you could do a list comprehension. Commented Jan 16, 2023 at 13:38
  • I've added in edit a solution with list comprehension and using np.array_equiv(), but I'm not sure if that's an optimal solution Commented Jan 16, 2023 at 14:04

1 Answer 1

1

Either you are using an old numpy version, or have deliberately omitted/ignored the warnings:

In [2]: from datetime import date
   ...: 
   ...: arr1 = np.array(
   ...: [np.array([date(2022,12,14)]),
   ...: np.array([date(2022,12,15)])]
   ...: )
   ...: 
   ...: arr2 = np.array(
   ...: [np.array([date(2022,12,14)]),
   ...: np.array([date(2022,12,19), date(2022, 12, 20), date(2022, 12, 21)])]
   ...: )
C:\Users\paul\AppData\Local\Temp\ipykernel_1604\1472092167.py:8: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
  arr2 = np.array(

Now look at the resulting arrays - they are quite different:

In [3]: arr1
Out[3]: 
array([[datetime.date(2022, 12, 14)],
       [datetime.date(2022, 12, 15)]], dtype=object)

In [4]: arr2
Out[4]: 
array([array([datetime.date(2022, 12, 14)], dtype=object),
       array([datetime.date(2022, 12, 19), datetime.date(2022, 12, 20),
              datetime.date(2022, 12, 21)], dtype=object)              ],
      dtype=object)

And the test:

In [5]: arr1 == arr1[0]
Out[5]: 
array([[ True],
       [False]])

In [6]: arr2 == arr2[0]
C:\Users\paul\AppData\Local\Temp\ipykernel_1604\3122922660.py:1: DeprecationWarning: elementwise comparison failed; this will raise an error in the future.
  arr2 == arr2[0]
Out[6]: False

Again a warning that you are doing something wrong.

Look at the list comprehension:

In [7]: [np.array_equiv(arr2[0], dates) for dates in arr2]
Out[7]: [True, False]

Or with the simple equality that worked for arr1:

In [8]: [dates==arr2[0] for dates in arr2]
Out[8]: [array([ True]), array([False, False, False])]

Notice that the 2nd comparison has a value for each element of the inner array.

Object dtype arrays are a lot like lists, and arrays containing arrays which themselves are object dtype are especially complicated.

Sign up to request clarification or add additional context in comments.

1 Comment

For some reason I wasn't getting any warnings before, now that I reopen python interpreter I'm getting the warning once but only once - when I run the same line again or redefine a variable it doesn't show anymore. Alright then, I'll stick with the [7] list comprehension then, thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.