What is the proper way to adaptively affect elements of a numpy array? I came up with 2 methods: Using masks, and using numpy's where function:
import numpy as np
from numpy.core.umath_tests import inner1d
import time
# Make a large array of 3d points & iterate
vec = np.random.rand(1000000,3) * 100
# Method 1: Iterate with MASK
def MASK():
vec0 = np.array(vec)
while True:
# Calculate magnitudes and generate mask
mag = inner1d(vec0,vec0)
mask = mag >= 1
# If all masks = False, break
if not np.ma.max(mask):
break
# Apply fancy expensive math on desired elements
vec0[mask] = vec0[mask] * 0.5
return vec0
# Method 2: Iterate with WHERE
def WHERE():
vec1 = np.array(vec)
while True:
#Calculate magnitudes
mag = inner1d(vec1,vec1)
# If all magnitudes meet criteria, break
if (mag < 1).all():
break
# Apply fancy expensive math on desired elements
vec1[np.where(mag >= 1)] *= 0.5
return vec1
t = time.time()
m = MASK()
t = time.time() - t
print 'MASK: %s'%t
t = time.time()
w = WHERE()
t = time.time() - t
print 'WHERE: %s'%t
print np.allclose(m,w)
Results:
>>>
MASK: 0.586141109467
WHERE: 0.477689981461
True
>>>
Method #2 was slightly faster, which is good! Are there any other methods to do this more efficiently?