Python 使用掩蔽数组的行计算数组行的平均值

Python 使用掩蔽数组的行计算数组行的平均值,python,numpy,scipy,octave,Python,Numpy,Scipy,Octave,在将这行简单的倍频程代码转换为Python时,我想知道是否有一种更快/更干净的方法: 给定两个矩阵,倍频程命令使用布尔矩阵R对一行矩阵Y求平均值,以标记感兴趣的值: load (‘mydata.mat’) row1_mean = mean( Y(1, R(1, :) ) ) 又好又快又简单。在Python中尝试这样做要简洁得多,但到目前为止,我可以这样做: import numpy as np from scipy import io as spio myDict = spio.loadma

在将这行简单的倍频程代码转换为Python时,我想知道是否有一种更快/更干净的方法:

给定两个矩阵,倍频程命令使用布尔矩阵
R
对一行矩阵
Y
求平均值,以标记感兴趣的值:

load (‘mydata.mat’)
row1_mean = mean( Y(1, R(1, :) ) )
又好又快又简单。在Python中尝试这样做要简洁得多,但到目前为止,我可以这样做:

import numpy as np
from scipy import io as spio

myDict = spio.loadmat(‘mydata.mat’)
Y_mat = myDict['Y']
R_mat = myDict['R']

maskR = ~R_mat.astype(bool)[0][:]                      # row as boolean so we can invert it
maskR = maskR.astype(int)                              # turn it back to 1s & 0s

maskedY = np.ma.masked_array(Y_mat[0][:], mask=maskR)  # mask row of Y with R matrix

row1_mean = maskedY.mean()                             # get the mean
means = np.nanmean(np.where(mask, arr, np.nan), axis=1)
# if every value in a given row is masked, the mean will be calculated as nan. Change those to zeros
means[np.isnan(means)] = 0
我可能错过了一个更好的方法。 特别是,有没有更简单的方法来反转1和0的矩阵? 也许还有一种更直接的方法来获得数组切片的平均值(我知道关于轴的问题),但考虑到掩蔽数组

拿蒙面的小妞来说 如果我了解您正试图正确执行的操作,这里有一个更好的方法:

row1_mean = Y_mat[0][R_mat[0].astype(bool)].mean()
如果你只想知道一行的平均值。您可以按如下方式计算每行的平均值:

import numpy as np
from scipy import io as spio

myDict = spio.loadmat(‘mydata.mat’)
Y_mat = myDict['Y']
R_mat = myDict['R']

maskR = ~R_mat.astype(bool)[0][:]                      # row as boolean so we can invert it
maskR = maskR.astype(int)                              # turn it back to 1s & 0s

maskedY = np.ma.masked_array(Y_mat[0][:], mask=maskR)  # mask row of Y with R matrix

row1_mean = maskedY.mean()                             # get the mean
means = np.nanmean(np.where(mask, arr, np.nan), axis=1)
# if every value in a given row is masked, the mean will be calculated as nan. Change those to zeros
means[np.isnan(means)] = 0
Numpy中的布尔索引 作为将来使用的注意事项,您实际上可以使用布尔数组为Numpy数组编制索引(我想就像倍频程一样?)。下面是一个简单的例子:

import numpy as np

arr = np.arange(10*5).reshape(10,5)
mask = np.random.randint(0, 2, (10, 5), dtype=bool)

print('original array\n%s\n' % arr)
print('boolean masked array\n%s\n' % arr[mask])
输出:

original array
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]
 [20 21 22 23 24]
 [25 26 27 28 29]
 [30 31 32 33 34]
 [35 36 37 38 39]
 [40 41 42 43 44]
 [45 46 47 48 49]]

boolean masked array
[ 1  2  3  4  7  8 10 11 12 14 15 19 26 27 29 33 38 39 44 45 46]

如您所见,布尔索引将使2D数组变平(原因由Paul Panzer在评论中解释)。这就是为什么我在上面的第二个答案中使用了
np。其中

如果您想使用掩码数组,下面是一种简化的方法:

import numpy as np

# create some mock data
R_mat = np.arange(16).reshape(4, 4)
Y_mat = np.random.randint(0, 2, (4, 4))

R_mat
# array([[ 0,  1,  2,  3],
#        [ 4,  5,  6,  7],
#        [ 8,  9, 10, 11],
#        [12, 13, 14, 15]])
Y_mat
# array([[0, 1, 0, 1],
#        [0, 1, 1, 0],
#        [0, 1, 0, 1],
#        [0, 0, 1, 0]])

# compute all row means or all column means at once
# use Y_mat==0 to invert and convert to bool in one go
row_means = np.ma.MaskedArray(R_mat, Y_mat==0).mean(axis=1)
col_means = np.ma.MaskedArray(R_mat, Y_mat==0).mean(axis=0)

row_means
# masked_array(data=[2.0, 5.5, 10.0, 14.0],
#              mask=[False, False, False, False],
#        fill_value=1e+20)
col_means
# masked_array(data=[--, 5.0, 10.0, 7.0],
#              mask=[ True, False, False, False],
#        fill_value=1e+20)


# or take just one row or column and get the mean 
np.ma.MaskedArray(R_mat, Y_mat==0)[2].mean()
# 10.0
np.ma.MaskedArray(R_mat, Y_mat==0)[:, 0].mean()
# masked
如果出于某种原因,您希望避免屏蔽阵列:

nrow, ncol = R_mat.shape

I, J = np.where(Y_mat)
row_means = np.bincount(I, R_mat[I, J], nrow) / np.bincount(I, None, nrow)

J, I = np.where(Y_mat.T)
col_means = np.bincount(J, R_mat[I, J], ncol) / np.bincount(J, None, ncol)
# __main__:1: RuntimeWarning: invalid value encountered in true_divide

row_means
# array([ 2. ,  5.5, 10. , 14. ])
col_means
# array([nan,  5., 10.,  7.])

你能给出一个示例输入和预期输出吗?将一个1和0的数组倒置:
1-arr
1^arr
np.array([1,0])[arr]
你可能需要转换以下表达式,该表达式给出了一个包含每行均值的向量:
row_mean=sum(Y.*R,2)。/sum(R,2)我认为第二种方法行不通,因为假设Y_-mat和R_-mat具有相同的形状,布尔索引将导致平面数组。这是必须的,因为一般来说,Trues的数量,即结果数组的大小可以是任何东西。我不想成为一个讨厌的人,但我认为OP希望删除屏蔽值,而不是将其置零。这使得平均值的分母有所不同。我总是很高兴得到反馈。感谢您花时间:)倍频程还使用布尔索引将数组展平,因此
arr[mask]
实际上相当于问题中的代码。很好-不知道如何使用数组索引数组,exp a bool one。好消息。