I will detail here the more general solution that uses a masked array. To illustrate the details let's create an lower triangular matrix with only ones:
matrix = np.tril(np.ones((5, 5)), 0)
If you the terminology above is not clear this matrix looks like this:
[[ 1., 0., 0., 0., 0.],
[ 1., 1., 0., 0., 0.],
[ 1., 1., 1., 0., 0.],
[ 1., 1., 1., 1., 0.],
[ 1., 1., 1., 1., 1.]]
Now, we want our function to return an average of 1 for each of rows. Or in other words that the mean over the axis 1 is equal to a vector of five ones. In order to achieve this we created a masked matrix where the entries whose values are zero are considered invalid. This can be achieved withnp.ma.masked_equal
:
masked = np.ma.masked_equal(matrix, 0)
Finally we perform numpy operations in this array that will systematically ignore the masked elements (the 0's). With this in mind we obtain the desired result by:
masked.mean(axis=1)
This should produce a vector whose entries are only ones.
In more detail the output of np.ma.masked_equal(matrix, 0)
should look like this:
masked_array(data =
[[1.0 -- -- -- --]
[1.0 1.0 -- -- --]
[1.0 1.0 1.0 -- --]
[1.0 1.0 1.0 1.0 --]
[1.0 1.0 1.0 1.0 1.0]],
mask =
[[False True True True True]
[False False True True True]
[False False False True True]
[False False False False True]
[False False False False False]],
fill_value = 0.0)
This indicates that eh values on --
are considered invalid. This is also shown in the mask attribute of the masked arrays as True which indicates that IT IS an invalid element and therefore should be ignored.
Finally the output of the mean operation on this array should is:
masked_array(data = [1.0 1.0 1.0 1.0 1.0],
mask = [False False False False False],
fill_value = 1e+20)