New to python and need some help. I have a numpy array tuple with a shape of (1, 8760) with numbers within each of the 8760 locations. I've been trying to calculate if the values is between -2 and 2 then my new variable will be 0 else just keep the same value in the new variable. Here is what I tried and many others but I probably don't understand the array concept fully.
for x in flow:
if 2 > x < -2:
lflow = 0
else:
lflow = flow
I get this error:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
From what I read those functions gives me a true or false but I want to calculate of value instead of telling me if it matches or not. Please help.
Thanks
If your shape is (1,8760) an array of 8760 elements is assigned to x in your iteration, because the loop iterates the first axis containing one element of size 8760.
Furthermore I'd suggest to use "where" function instead of a loop:
# create a random array with 100 values in the range [-5,5]
a = numpy.random.random(100)*10 - 5
# return an array with all elements within that range set to 0
print numpy.where((a < -2) | (a > 2), a, 0)
Numpy uses boolean masks to select or assign values to arrays in bulk. For example, given the array
A = np.array([-3,-1,-2,0,1,5,2])
This mask represents all the values in A that are less than -2 or greater than 2
mask = (A < -2) | (A > 2)
Then use it to assign those values to 0
A[mask] = 0
This is much faster than using a regular loop in python, since numpy will perform this operation in c or fortran code
Related
Posing the title of this question differently.
I have a function that take a three dimensional array and masks certain elements within the array based on specific conditions. See below:
#function for array masking
def masc(arr,z):
return(np.ma.masked_where((arr[:,:,2] <= z+0.05)*(arr[:,:,2] >= z-0.05), arr[:,:,2]))
arr is a 3D array and z is a single value.
I now want to iterate this for multiple Z values. Here is an example with 2 z values:
masked_array1_1 = masc(xyz,z1)
masked_array1_2 = masc(xyz,z2)
masked_1 = masked_array1_1.mask + masked_array1_2.mask
masked_array1 = np.ma.array(xyz[:,:,2],mask=masked_1)
The masked_array1 gives me exactly what i'm looking for.
I've started to write a forloop to iterate this over a 1D array of Z values:
mask_1 = xyz[:,:,2]
for i in range(Z_all_dim):
mask_1 += (masc(xyz,Z_all[i]).mask)
masked_array1 = np.ma.array(xyz[:,:,2], mask = mask_1)
Z_all is an array of 7 unique z values. This code does not work (the entire array ends up masked) but i feel like i'm very close. Does anyone see if i'm doing something wrong?
Your issue is that before the loop you start with mask_1 = xyz[:,:,2]. Adding a boolean array to a float will cast the boolean to 1s and 0s and unless your float array has any 0s in it, the final array will be all nonzero values, which then causes every value to get masked. Instead do
mask_1 = masc(xyz, Z_all[0]).mask
for z in Z_all[1:]:
mask_1 += masc(xyz, z).mask
Or avoiding any loops and broadcasting your operations
# No need to pass it through `np.ma.masked_where` if
# you're just going to extract just the boolean mask
mask = (xyz[...,2,None] <= Z_all + 0.05) * (xyz[...,2,None] >= Z_all - 0.05)
mask = np.any(mask, axis=-1)
So I'm currently trying to implement a perceptron, and I have two NumPy arrays, dimensions are 1x200. I would like to check each and every element in the two matrices against each other, and get back the sum of the elements which doesn't match each other. I tried doing something like this:
b = (x_A > 0).astype(int)
b[b == 0] = -1
Now I want to compare this matrix with the other, my question is therefore, is there a way to avoid for-loops and still get what I want (the sum of elements which doesn't match)?
You should just be able to do this directly - assuming that your arrays are of the same dimensions. For numpy arrays a and b:
np.sum(a != b)
a != b gives an array of Booleans (True when they are not equal element-wise and False when they are). Sum will give you the count of all elements that are not equal.
I have a simple numpy 2D Array. E.g. :
M=np.array([[15,1,0],
[19,5,2]])
which I loop over to check if in each line (axis 1)
a value exist greater than e.g. 2.
As the first value is always greater than 2, I slice the array to only check which of the other n values in that line is greater than 2.
#A
for i in range(len(M)):
if any(M[i,1:])>=2:
disp('Super')
Or, as I am not so familiar with python yet, I also used this code, which should function the same, right?
#B
for i in range(len(M)):
if any(x>=2 in x in M[i,1:]):
disp('Great')
The Problem I have now is that the any does not care about my slicing (M[i,1:]). It checks always the total array and of course finding a value greater than 2.
I expected in the first itteration a FALSE and in the second a TRUE
any(l) takes a list (or iterable) of values and returns True if any of the values it iterated over are truthy i.e. bool(value) == True. Therefore, it doesn't make sense to compare the output of any(...) with a number so I wouldn't do any(M[i,1:])>=2.
However, you can do any(M[i, 1:] > 2) where M[i, 1:] > 2 broadcasts the greater than operator to each value of the given row and returns you a boolean array that any can operate over.
Something is wrong in my script and I found the error, but I'm completely stuck.
there is array b which contains two elements:
b = np.zeros ((1,2))
b[0,0] = 272
b[0,1] = 1578
I want to check if there are elements in the second columns, greater than a value, and if so, assign that value a zero.
the command
b[ b[:,1] >= 1000 ] = 0
changes both elements to 0 instead of b[0,1]
what am I missing?
thanks in advance
C
If I understand you correctly, you only want to set the second column to zero (if its value is >1000)? I extended your example to have at least two rows, but just tested it to work also with one:
b = np.array([[123, 456],
[789, 101112]])
mask = b[:,1] > 1000
b[mask,1] = 0
print b
I defined mask to explain it better - you can substitute it in.
mask is then a boolean vector with one element for each row, in this case [False, True]. In the last step, that mask is used to mask out the selected rows and assign zero to the first column element.
I think you could loop over b ?
b_rows = 1 #number of your rows
for i in range(b_rows):
if b[i,1] >= 1000:
b[i,1]=0
I'm still very new to python and programing and I'm trying to figure out if I'm going about this problem in the correct fashion. I tend to have a matlab approach to things but here I'm just struggling...
Context:
I have two numpy arrays plotted in this image on flickr since I can't post photos here :(. They are of equal length properties (both 777x1600) and I'm trying to use the red array to help return the index(value on the x-axis of plot) and element value(y-axis) of the point in the blue plot indicated by the arrow for each row of the blue array.
The procedure I've been tasked with was to:
a) determine max value of red array (represented with red dot in figure and already achieved)
and b) Start at the end of the blue array with the final element and count backwards, comparing element to preceding element. Goal being to determine where the preceding value decreases. (for example, when element -1 is greater than element -2, indicative of the last peak in the image). Additionally, to prevent selecting "noise" at the tail end of the section with elevated values, I also need to constrain the selected value to be larger than the maximum of the red array.
Here's what I've got so far, but I'm stuck on line two where I have to evaluate the selected row of the array from the (-1) position in the row to the beginning, or (0) position:
for i,n in enumerate(blue): #select each row of blue in turn to analyze
for j,m in enumerate(n): #select each element of blue ??how do I start from the end of array and work backwards??
if m > m-1 and m > max_val_red[i]:
indx_m[i] = j
val_m[i] = m
To answer you question directly, you can use n[::-1] to reverse the arrray n.
So the code is :
for j, m in enumerate(n[::-1]):
j = len(n)-j-1
# here is your code
But to increase calculation speed, you should avoid python loop:
import numpy as np
n = np.array([1,2,3,4,2,5,7,8,3,2,3,3,0,1,1,2])
idx = np.nonzero(np.diff(n) < 0)[0]
peaks = n[idx]
mask = peaks > 3 # peak muse larger than 3
print "index=", idx[mask]
print "value=", peaks[mask]
the output is:
index= [3 7]
value= [4 8]
I assume you mean:
if m > n[j-1] and m > max_val_red[i]:
indx_m[i] = j
val_m[i] = m
because m > m - 1 is always True
To reverse an array on an axis you can index the array using ::-1 on that axis, for example to reverse blue on axis 1 you can use:
blue_reverse = blue[:, ::-1]
Try and see you can write your function as a set of array operations instead of loops (that tends to be much faster). This is similar to the other answer, but it should allow you avoid both loops you're currently using:
threshold = red.max(1)
threshold = threshold[:, np.newaxis] #this makes threshold's shape (n, 1)
blue = blue[:, ::-1]
index_from_end = np.argmax((blue[:, :-1] > blue[:, 1:]) & (blue[:, :-1] > threshold), 1)
value = blue[range(len(blue)), index_from_end]
index = blue.shape[1] - 1 - index_from_end
Sorry, I didn't read all of it but you can possibly look into the built in function reversed.
so instead of enumerate( n ). you can do reversed( enumerate( n ) ). But then your index would be wrong the correct index would be eval to len( n ) - j