2

I discovered that numpy.where behaves differently when applied on a condition such as foo==2 when foo is a list or foo is a numpy.array

foo = ["a","b","c"]
bar = numpy.array(["a","b","c"])
numpy.where(foo == "a") # Returns array([])
numpy.where(bar == "a") # Returns array([0])

I want the same command to make this applicable to either list or numpy.array, and I am concerned about how to perform this efficiently. Is the following ok ?

numpy.where(numpy.array(foo, copy=False) == "a") # Returns array([0])
numpy.where(numpy.array(bar, copy=False) == "a") # Returns array([0])

Result is as expected, but is this the best way to answer my need ? Using each time numpy.array constructor is the best way to ensure object type ?

Thanks !

1
  • 3
    Note that your problem comes from foo == "a" and bar == "a" and not np.where. Lists do not behave like numpy arrays. Expecting anything but False from ["a","b"] == "b" is as absurd as expecting list() == str() to give an array. Commented Sep 13, 2016 at 15:43

2 Answers 2

3

If you are really looking for the most numpy-esque solution, use np.asarray:

numpy.where(numpy.asarray(foo) == "a")

And if you also want your code to work with subclasses of numpy.ndarray, without "downconverting" them to their base class of ndarray, then use np.asanyarray:

numpy.where(numpy.asanyarray(foo) == "a")

This works for np.matrix for instance, without converting it to an array. I suppose that this would also ensure that the np.matrix instance doesn't get copied or reconstructed into an array prior to checking.

Note: I think that copies are made by np.array for lists, because it needs to construct the array object. This can be seen in the documentation for np.array:

copy : bool, optional
    If true (default), then the object is copied.
    Otherwise, a copy will only be made if __array__ returns a copy, if
    obj is a nested sequence, or if a copy is needed to satisfy any of the
    other requirements (dtype, order, etc.).

np.asarray would also make a copy in this case.

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

1 Comment

numpy.asanyarray is preferred and working. Thanks for highlighting numpy.array constructor may copy object even if copy=False is provided !
2

To me your solution is already the best:

numpy.where(numpy.array(foo, copy=False) == "a")

It is concise, very clear and totaly efficient thanks to copy=False.

Comments

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.