Array logic

TME 310 - Computational Physical Modeling

Lorne Arnold, PhD, PE

University of Washington Tacoma

Logical expressions

We have already seen logical expressions in places like while loops:

while logical_expression:
    # execute something

Logical expressions evaluate whether something is true or false. They result in a boolean value (True or False in Python).

x = 0
while x < 2:
    print(x)
    x += 1
0
1

Array indexing

We’ve also seen that we can access specific portions of arrays with indexing.

import numpy as np
x = np.linspace(0,100,6)
print(x)
[  0.  20.  40.  60.  80. 100.]

We can access individual elements or slices:

x[0]: 0.0
x[-1]: 100.0
x[2:4]: [40. 60.]

Logical indexing

Logical indexing combines these two ideas.

  • A logical expression with an array results in a logical array (sometimes called a mask):
x = np.array([1.32, 1.1, 0.3, 3.8, -5.2]) # <-- an array of random numbers
logical_array = x < 1
print(f"logical_array: {logical_array}")
logical_array: [False False  True False  True]
  • Indexing an array with a logical array returns only the entries of the array where the logical array is True.
x[logical_array]
array([ 0.3, -5.2])

Logical AND/OR with arrays

We can combine logical tests in numpy with the bitwise “AND” operator, &, or the bitwise “OR” operator, |.

The result of logical tests connected by & is only True if BOTH statements are true. The result of logical tests connected by | is True if EITHER statements are true.

arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
# What values of arr are greater than 3 AND less than 7?
print(arr[(arr > 3) & (arr < 7)]) # <--- each test in ()!
[4 5 6]
# What values of arr are greater than 6 OR less than 2?
print(arr[(arr > 6) | (arr < 2)])
[ 1  7  8  9 10]

Solve with logical array

# Initial arrays x and y:
x = np.linspace(0,4)
y = 1.27**(2.3*x)
# Create a mask using the test condition on y:
logical_mask = y > 4.0
# Apply the mask to the related array, x:
x_masked = x[logical_mask]
# Select the first entry in the masked version of x:
answer = x_masked[0]
print(f"x_masked: {x_masked}")
print(f"answer: {answer:.2f}")
x_masked: [2.53061224 2.6122449  2.69387755 2.7755102  2.85714286 2.93877551
 3.02040816 3.10204082 3.18367347 3.26530612 3.34693878 3.42857143
 3.51020408 3.59183673 3.67346939 3.75510204 3.83673469 3.91836735
 4.        ]
answer: 2.53

What about values of x slightly smaller than 2.53061224?

Plots with masked arrays

See if you can re-create the plots of these array masking examples: (hint: some use np.random.rand())