Reputation: 3734
I have a 2D numpy array where column 0 is the pan rotation of a device and column 1 is the tilt rotation. Each row is a different fixture. I want to run the following logic on each row:
if(pantilt[0] > 90):
pantilt[0] -=180
pantilt[1] *= -1
elif pantilt[0] < -90:
pantilt[0] += 180
pantilt[1] *= -1
I understand basic conditional operations on 1D like myarray[condition] = something. But I can't extrapolate that into more dimensions.
Upvotes: 2
Views: 507
Reputation: 221754
Inspired by this another related answer
, one can use masking
in three steps, instead of four steps as proposed in the other two solutions, like so -
import numpy as np
# Get mask correspindig to IF conditional statements in original code
mask_lt = pantilt[:,0]<-90
mask_gt = pantilt[:,0]>90
# Edit the first column as per the statements in original code
pantilt[:,0][mask_gt] -= 180
pantilt[:,0][mask_lt] += 180
# Edit the second column as per the statements in original code
pantilt[ mask_lt | mask_gt,1] *= -1
Runtime tests
Quick runtime tests to compare the three approaches listed so far -
In [530]: num_samples = 10000
...: org = np.random.randint(-180,180,(num_samples,2))
...:
In [531]: pantilt = org.copy()
In [532]: %timeit hpaulj_mask4(pantilt)
10000 loops, best of 3: 27.7 µs per loop
In [533]: pantilt = org.copy()
In [534]: %timeit maxymoo_mask4(pantilt)
10000 loops, best of 3: 33.7 µs per loop
In [535]: pantilt = org.copy()
In [536]: %timeit mask3(pantilt) # three-step masking approach from this solution
10000 loops, best of 3: 22.1 µs per loop
Upvotes: 1
Reputation: 231738
I would calculate a mask, or boolean index, and use if for each column:
Construct a sample array:
pantilt=np.column_stack([np.linspace(-180,180,11),np.linspace(0,90,11)])
I = pantilt[:,0]>90
# J = pantilt[:,0]<-90
pantilt[I,0] -= 180
pantilt[I,1] *= -1
I = pantilt[:,0]<-90 # could use J instead
pantilt[I,0] += 180
pantilt[I,1] *= -1
Before:
array([[-180., 0.],
[-144., 9.],
[-108., 18.],
[ -72., 27.],
[ -36., 36.],
[ 0., 45.],
[ 36., 54.],
[ 72., 63.],
[ 108., 72.],
[ 144., 81.],
[ 180., 90.]])
After:
array([[ 0., -0.],
[ 36., -9.],
[ 72., -18.],
[-72., 27.],
[-36., 36.],
[ 0., 45.],
[ 36., 54.],
[ 72., 63.],
[-72., -72.],
[-36., -81.],
[ 0., -90.]])
This would work just as well if the columns were separate 1d arrays.
Upvotes: 2
Reputation: 36555
How about this:
pantilt[:,0][pantilt[:,0]>90] -= 180
pantilt[:,1][pantilt[:,0]>90] *= -1
pantilt[:,0][pantilt[:,0]<-90] += 180
pantilt[:,1][pantilt[:,0]<-90] *= -1
Upvotes: 2