1

I saw this code in some examples online and am trying to understand and modify it:

c = a[b == 1]
  1. Why does this work? It appears b == 1 returns true for each element of b that satisfies the equality. I don't understand how something like a[True] ends up evaluating to something like "For all values in a for which the same indexed value in b is equal to 1, copy them to c"

a,b, and c are all NumPy arrays of the same length containing some data. I've searched around quite a bit but don't even know what to call this sort of thing.

  1. If I want to add a second condition, for example:
c = a[b == 1 and d == 1]

I get

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

I know this happens because that combination of equality operations is ambiguous for reasons explained here, but I am unsure of how to add a.any() or a.all() into that expression in just one line.

EDIT:

For question 2, c = a[(b == 1) & (d == 1)] works. Any input on my first question about how/why this works?

Salvatore
  • 10,815
  • 4
  • 31
  • 69
  • 1
    try `c = a[(b == 1) & (d == 1)]` – Yuca Apr 04 '19 at 21:46
  • That answers my second question nicely and works as expected. Do you have any input on part 1? – Salvatore Apr 04 '19 at 21:48
  • your part 1 is too broad. instead of why does this work it would be nice to present a more specific question. That way is easier for me to help you :) – Yuca Apr 04 '19 at 21:50
  • @Yuca, updated with some more info. – Salvatore Apr 04 '19 at 21:55
  • 1
    the best way for you to wrap your head around what's going on is to look at b == 1. without sample data I can't provide a concrete example but if b is an array of size 10, `b == 1` will return 10 booleans. This new array of booleans serves as a valid index for the array a – Yuca Apr 04 '19 at 21:57

2 Answers2

0

You just need to put the conditions separately in brackets. Try using this

c = a[(b == 1) & (d == 1)]
razdi
  • 1,388
  • 15
  • 21
0

Why wouldn't your example in point (1) work? This is Boolean indexing. If the arrays were different shapes then it may be a different matter, but:

c = a[b == 1]

Is indistinguishable from:

c = a[a == 1]

When you don't know the actual arrays. Nothing specific to a is going on here; a == 1 is just setting up a boolean mask, that you then re-apply to a in a[mask_here]. Doesn't matter what generated the mask.

roganjosh
  • 12,594
  • 4
  • 29
  • 46
  • 1
    Part 1 does work. The question was why it worked and what to call it, and this answer of boolean indexing is exactly what I was looking for. The post you liked is exactly the kind of documentation I've been trying to find. – Salvatore Apr 04 '19 at 22:08
  • 1
    @MatthewSalvatoreViglione you're welcome. I struggled to get my head around the fact that the syntax is actually acting in two independent parts too :) – roganjosh Apr 04 '19 at 22:09