Greetings:
In some of my code, I need to use large matrix of random numbers that
meet specific criteria (i.e., some random numbers need to be removed and
replaces with new ones).
I have been working with .any() and .where() to facilitate this process.
In the code below, .any() is used in a while loop to test for the
presence of matrix elements that do not meet criteria. After that,
.where() is used to obtain the tuple of indices of elements that do not
meet criteria. I then use iteration over the tuple of indices and
replace each 'bad' random number one at a time.
Here's an example:
>>> a=numpy.random.normal(0,1,(3,3))
>>> a
array([[ 0.79653228, -2.28751484, 1.15989261],
[-0.7549573 , 2.35133816, 0.22551564],
[ 0.85666713, 1.17484243, 1.18306248]])
>>> while (a<0).any() or (a>1).any():
ind=numpy.where(a<0)
for aa in xrange(len(ind[0])):
a[ind[0][aa],ind[1][aa]]=numpy.random.normal(0,1)
ind=numpy.where(a>1)
for aa in xrange(len(ind[0])):
a[ind[0][aa],ind[1][aa]]=numpy.random.normal(0,1)
>>> a
array([[ 0.79653228, 0.99298488, 0.24903299],
[ 0.10884186, 0.10139654, 0.22551564],
[ 0.85666713, 0.76554597, 0.38383126]])
>>>
My main question: is there a more efficient approach that I could be
using? I would ideally like to be able to remove the two for loops.
An ancillary question: I don't quite see why the test in the while loop
above works fine, however, the following formation does not.
>>> while (0<a<1).any():
ind=numpy.where(a<0)
for aa in xrange(len(ind[0])):
a[ind[0][aa],ind[1][aa]]=numpy.random.normal(0,1)
ind=numpy.where(a>1)
for aa in xrange(len(ind[0])):
a[ind[0][aa],ind[1][aa]]=numpy.random.normal(0,1)
print type(ind)
Traceback (most recent call last):
File "<pyshell#71>", line 1, in <module>
while (0<a<1).any():
ValueError: The truth value of an array with more than one element is
ambiguous. Use a.any() or a.all()
>>>
Can someone clarify this?
Thanks,
-Mark