Reputation: 2217
I want to find the means of all the negative numbers from a list that has a mix of positive and negative numbers. I can find the mean of the lists as
import numpy as np
listA = [ [2,3,-7,-4] , [-2,3,4,-5] , [-5,-6,-8,2] , [9,5,13,2] ]
listofmeans = [np.mean(i) for i in listA ]
I want to create a similar one line code that only takes the mean of the negative numbers in the list. So for example the first element of the new list would be (-7 + -4)/2 = -5.5
My complete list would be:
listofnegativemeans = [ -5.5, -3.5, -6.333333, 0 ]
Upvotes: 6
Views: 15995
Reputation: 18628
The pure numpy way :
In [2]: np.ma.masked_greater(listA,0).mean(1).data
Out[2]: array([-5.5 , -3.5 , -6.33333333, 0. ])
Upvotes: 1
Reputation: 7588
That would be something like:
listA = np.array( [ [2,3,-7,-4] , [-2,3,4,-5] , [-5,-6,-8,2] , [9,5,13,2] ] )
listofnegativemeans = [np.mean(i[i<0]) for i in listA ]
output:
[-5.5, -3.5, -6.333333333333333, nan]
Zero is misleading, I definitely prefer nan
if you don't have any elements that are negative.
Upvotes: 0
Reputation: 362647
If you're using numpy at all, you should strive for numpythonic code rather than falling back to python logic. That means using numpy's ndarray data structure, and the usual indexing style for arrays, rather than python loops.
For the usual means:
>>> listA
[[2, 3, -7, -4], [-2, 3, 4, -5], [-5, -6, -8, 2], [9, 5, 13, 2]]
>>> A = np.array(listA)
>>> np.mean(A, axis=1)
array([-1.5 , 0. , -4.25, 7.25])
Negative means:
>>> [np.mean(row[row<0]) for row in A]
[-5.5, -3.5, -6.333333333333333, nan]
Upvotes: 2
Reputation: 11961
You could use the following:
listA = [[2,3,-7,-4], [-2,3,4,-5], [-5,-6,-8,2], [9,5,13,2]]
means = [np.mean([el for el in sublist if el < 0] or 0) for sublist in listA]
print(means)
Output
[-5.5, -3.5, -6.3333, 0.0]
If none of the elements in sublist
are less than 0
, the list comprehension will evaluate to []
. By including the expression [] or 0
we handle your scenario where you want to evaluate the mean of an empty list to be 0
.
Upvotes: 5