-1

I have already tried looking at other similar posts however, their solutions do not solve this specific issue. Using the answer from this post I found that I get the error: "The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()" because I define my array differently from theirs. Their array is a size (n,) while my array is a size (n,m). Moreover, the solution from this post does not work either because it applies to lists. The only method I could think of was this:

When there is at least 1 True in array, then entire array is considered True:

filt = 4
tracktruth = list()
arraytruth = list()
arr1 = np.array([[1,2,4]])
for track in range(0,arr1.size):
    if filt == arr1[0,track]:
        tracktruth.append(True)
    else:
        tracktruth.append(False)

if any(tracktruth):
    arraytruth.append(True)
else:
    arraytruth.append(False)

When there is not a single True in array, then entire array is considered False:

filt = 5
tracktruth = list()
arraytruth = list()
arr1 = np.array([[1,2,4]])
for track in range(0,arr1.size):
    if filt == arr1[0,track]:
        tracktruth.append(True)
    else:
        tracktruth.append(False)

if any(tracktruth):
    arraytruth.append(True)
else:
    arraytruth.append(False)

The reason the second if-else statement is there is because I wish to apply this mask to multiple arrays and ultimately create a master list that describes which arrays are true and which are false in their entirety. However, with a for loop and two if-else statements, I think this would be very slow with larger arrays. What would be a faster way to do this?

Tom
  • 55
  • 6
  • So you just want to check whether value is in nested array? – xana Mar 06 '20 at 21:33
  • What's an example where `.any()` doesn't give you the result you want? – Kelly Bundy Mar 06 '20 at 21:41
  • @pierogi I edited my original post for clarity. I want to see if there are any values that are less than the defined numerical value. – Tom Mar 06 '20 at 21:49
  • @HeapOverflow I edited the original post to show both instances. – Tom Mar 06 '20 at 21:50
  • 1
    I still don't really see test data. I see a bunch of code (and it's not clear whether it's correct), but I don't really see what's the the input data and what's the desired output data. – Kelly Bundy Mar 06 '20 at 21:52

4 Answers4

1

You can do this with list comprehension. I've done it here for one array but it's easily extended to multiple arrays with a for loop

filt = 4
arr1 = np.array([[1,2,4]])
print(any([part == filt for part in arr1[0]]))
Alistair
  • 589
  • 3
  • 11
1

You can get the arraytruth more generally, with list comprehension for the array of size (n,m)

import numpy as np

filt = 4
a = np.array([[1, 2, 4]])
b = np.array([[1, 2, 3],
              [5, 6, 7]])

array_lists = [a, b]

arraytruth = [True if a[a==filt].size>0 else False for a in array_lists]

print(arraytruth)

This will give you:

[True, False]
ywbaek
  • 2,971
  • 3
  • 9
  • 28
1

This seems overly complicated, you can use boolean indexing to achieve results without loops

arr1=np.array([[1,2,4]])

filt=4

arr1==filt

array([[False, False,  True]])

np.sum(arr1==filt).astype(bool)

True

With nmore than one row, you can use the row or column index in the np.sum or you can use the axis parameter to sum on rows or columns

As pointed out in the comments, you can use np.any() instead of the np.sum(...).astype(bool) and it runs in roughly 2/3 the time on the test dataset:

np.any(a==filt, axis=1)

array([ True])
G. Anderson
  • 5,815
  • 2
  • 14
  • 21
  • 1
    Very simple and cool method. Pretty much just needs two lines. I did not know one could add logic that way. – Tom Mar 06 '20 at 22:40
  • Vectorization of operations is really where numpy shines. While there are _some_ cases where you need to loop in numpy, they're really more edge-cases than the norm. Cheers! – G. Anderson Mar 06 '20 at 22:51
  • 1
    Does this differ from `(arr1 == filt).any()`? – Kelly Bundy Mar 06 '20 at 23:08
  • Good call, edited. I used `np.any()` instead of `array.any()` to match the rest of my answer, but the same principal applies – G. Anderson Mar 09 '20 at 14:47
1

[edit] Use numpy hstack method.

filt = 4
arr = np.array([[1,2,3,4], [1,2,3]])

print(any([x for x in np.hstack(arr) if x < filt]))
xana
  • 499
  • 3
  • 13