I have a series X, containing N values. I would like to select values of X subject to the condition X[i] > V. I would think that something like:
Y = X[(X[:] > V)]
Would work. For now, I am getting a null set, even though I know that a subset of the values in X fulfill this condition.
Am I writing this incorrectly?
The code you give is correct if you want to compare each X[i] with each V[i]. Notice
>>> import numpy as np
>>> x = np.array(range(5))
>>> v = np.array([3]*5)
>>> x[x > v]
array([4])
If the original is what you did want re-inspect your x and v. Notice you need not add an empty comprehension [:] to x, although it will not change the output. What it seems you want (from claiming this is not working) are all the x greater than any element of V? If so take the min of v and perform the same mask
x[x > np.min(v)]
Related
So I have 2 arrays
Arr_1=[a,b,c...]
Arr_2=[d,e,f..]
Now Arr_2 and its values are basically derived from performing some calculations on Arr_1.
Now Basically what I want to do is find out that first/minimum value of Arr_1 at which Arr_2's value is greater than a certain number.
Can anyone point out how to do that?
For example
Arr_1=[1,2,3,4]
Arr_2=[10,20,30,40]
So now I set the condition that Values in Arr_2 should be greater that 15.
And then I would like the desired output to be the first value of Arr_1 for which the corresponding value of Arr_2 satisfies this condition-i.e the output should be 2
Based on your now edited question, try below, You can modify it to meet your need
list1 = [2,3,4,5,6]
list2 = [1,33,4,5,2]
def test(value, items1,items2):
for x,y in zip(items1,items2):
if y > value:
print(f'array1 :{x} array2: {y}')
return x #<-- breaks on once the is first condition is met
test(15,list1,list2)
output
# array1: 3 array2: 33
You could iterate through both lists at the same time with zip like this:
for a_val, b_val in zip(arr1, arr2):
if (b_val > some_number):
print('something')
If this isn't what you're looking for, a little more clarification on the problem you're trying to solve would help.
If I understand your question correctly, then since the values in the second list are created based on some operation in the first, the indices of the values should be the same. You can use enumerate to get the indices. This should work:
Arr_1=[1,2,3,4]
Arr_2 = [10,20,30,40]
value = 15
for i, x in enumerate(Arr_2):
if x > value:
print(Arr_1[i])
break
I have used the break statement since you mentioned you only need the first value that satisfies the condition.
I want to iterate through a numpy ndarray and, if any values are less than X, replace one of them with X.
I have tried doing array_name[ array_name < X] = X but this replaces all of the values that are less than X.
I can use a for loop, but I feel like there's probably a more concise way already bundled with numpy.
for i in array_name:
if i < X:
i = X
break
Is there a way to do this more elegantly?
array_name < X
Returns same array but with True or False. Then you can just pick an index where the cell is True
idx = np.argwhere(array_name < X)[i]
array_name[idx] = value
Here, you can choose i arbitrarily
I am supposed to create a function that adds the absolute value of numbers that are larger than a certain number without using any python modules to do it. I wrote this:
def MatrixSumLarge(vals,large):
sum=0
sum1=0
sum2=0
i=0
#looking at the rows of the matrix
for i in range(len(vals[i])):
if abs(vals)>=large:
sum1=sum1+i
#lookinng at the columns of the matrix
for j in range(0,len(vals[j])):
if abs(vals[j])>=large:
sum2=sum2+vals[j]
sum=sum1+sum2
return(sum)
vals=[[1,-2.5,7,4],[-8,9,2,-1.5],[-12,7.5,4.2,11]]
# setting value of large
large = 7.1
#to print the final answer
print('b) Sum of Large Values = ',MatrixSumLarge(vals,large))
And got the error:
TypeError: bad operand type for abs(): 'list'
You vals is a list of list, so vals[i] is a list. However, abs() cannot be applied on a list, it should be applied on a number (floating number, integer, or complex number), see the official document here. You can for example, add an extra loop to add up the element in the row, like sum(abs(x) for x in vals[i] if x >= 2)
You can change 2 to the number you need.
Overall, your function could look something like this
def f(mat, v):
row_sums = [sum(abs(x) for x in row if x >= v) for row in mat]
return sum(row_sums)
From your question, it's not very clear to me whether you wanna
compare abs(x) to v or x to v
sum up abs(x) or x
But you should be able to adjust the code above to suit your need.
There is also a python module that helps you to flatten list of list. The function is called chain.from_iterable. So the above code could also be written like this
from itertools import chain
def f(mat, v):
sums = [sum(abs(x) for x in chain.from_iterable(mat) if x >= v]
return sum(sums)
I have a numpy.array called p2De. The first row has multiple elements may larger than 1. I want to set the elements which smaller than 1 to 1. Following is my code, but shows error... why? How to fix it?
bounde=1
p2De[:0]=map(lambda x:bounde if (x < bounde),p2Di[:0])
File "C:\Users\wange\workspace\cathode\src\diffusion.py", line 86
p2De[:0]=map(lambda x:bounde if (x < bounde),p2Di[:0])
^
SyntaxError: invalid syntax
You need to specify an else for your lambda function :
lambda x:bounde if (x < bounde) else #stuff
It should be
lambda x:bounde if (x < bounde) else x
You can also use list comprehension, which is more readable. Also, I would use the max builtin function instead of your lambda:
p2De[:0] = [max(x, bounde) for x in p2Di[:0]]
As others have noted, the syntax problem is in the lambda.
I don't think you want p2De[:0] - that's an empty array. p2De[0] is the 1st row. p2De[0,:] is the same, and makes it clear to the human readers that you have selected the 1st row of a 2d array.
The use of a map or comprehension works, but they don't offer much of an advantage, if any, over a simple loop (since you don't need to replace all of the values):
for i,v in enumerate(p2De[0,:]):
if v<1:
p2De[0,i] = 1
But none of these iterations is good numpy practice. You should try to think in terms of vector operations. A common practice is to use a boolean mask (or indexing) to select the values that should be changed:
I = p2De[0,:]<1 # boolean vector
p2De[0, I] = 1
p2De[0,p2De[0,:]<1]=1 # or one line form
There is also a numpy function that applies limits like this, np.maximum:
p2De[0,:] = np.maximum(p2De[0,:], 1)
np.clip applies both minimum and maximum bounds:
p2De[0,:] = np.clip(p2De[0,:], minbd, maxbd)
np.clip(p2De[0,:], minbd, maxbd, p2De[0,:]) # alt calling method
The Python(3) bosses encourage us to use functions and comprehensions over maps and lambdas. For example if plist was a list like your p2De[0,:] row:
def clip(x):
return 1 if x<1 else x
plist = [clip(x) for x in plist]
plist = [min(x, 1) for x in plist] # using a builtin for this simple case
say if you have a list a, you can do something like this:
a=[2,3,1,7,0,0,8]
bounde=1
b = map(lambda n: n if n > bounde else bounde,a)
print b
How to calculate mean of values of each list separately inside the list avoiding a special value (-999)?
A = [[4,5,7,8,-999],[3,8,5,7,-999]]
M = [sum(x)/len(x) for x in [y for y in A if y!= -999]
print (M)
Any idea ???
For best speed: can someone correct the following code? #alexanderlukanin13
M = [np.mean(L [L!=-999])for L in A]
As you mentioned numpy:
>>> import numpy as np
>>>
>>> A = [[4,5,7,8,-999],[3,8,5,7,-999]]
>>> M = [np.mean([x for x in L if x > -999]) for L in A]
>>> print M
[6.0, 5.75]
EDIT
As you mentioned speed as an important requirement, you can do this:
>>> B = np.array(A)
>>> np.average(B, axis=1, weights=B!=-999)
array([ 6. , 5.75])
Everything happens in numpy (i.e. C) space, which should get it pretty fast.
To explain a bit what is happening:
np.mean(A, axis=1) and the equivalent np.average(A, axis=1) compute the average over the columns of your array, i.e. the vector of means of each row, which is what you want. average allows the use of weights: we use B!=-999, which is a boolean array, evaluated as 1s and 0s when used as weights, i.e. ignoring the values evaluated as False.
A = [[4,5,7,8,-999],[3,8,5,7,-999]]
M = [sum(z)/float(len(z)) for z in [[x for x in y if x != -999] for y in A]]
print M
Output
[6.0, 5.75]
Using a generator function, and no need to create a new list in memory:
A = [[4,5,7,8,-999],[3,8,5,7,-999]]
def solve(lis, val):
for item in lis:
c = item.count(val) #count number of -999 in list
total = sum(item) - (val*c) #subtract it from total sum
yield float(total)/ (len(item) - c) #return mean
print list(solve(A, -999))
#[6.0, 5.75]