我有numpy.ndarray
大小为10000 x 20
的对象,我想要做的只是在每行上应用函数scipy.stats.mstats.zscore
但不考虑非负值。有什么想法吗?
# this works when considering all values
z_scores = st.mstats.zscore(data, axis=1, ddof=1)
# apparently, this does not work
z_scores = st.mstats.zscore(data[data>0], axis=1, ddof=1)
答案 0 :(得分:2)
scipy.stats.mstats
中的函数接受masked arrays。掩码阵列允许
你要指定一个掩码(一个布尔数组)来告诉mstats
函数
值得忽略。
因此,如果您创建一个掩盖了您想要忽略的值的蒙版数组:
mask = data <= 0
mdata = np.ma.masked_array(data, mask)
然后您可以使用以下方法计算所需的值:
zscores = mstats.zscore(mdata, axis=1, ddof=1)
例如,
import scipy.stats.mstats as mstats
import numpy as np
data = np.arange(12).reshape((3,4))
data[data % 3 == 0] = -1
mask = data <= 0
mdata = np.ma.masked_array(data, mask)
zscores = mstats.zscore(mdata, axis=1, ddof=1)
print(zscores)
产量
[[-- -0.7071067811865475 0.7071067811865475 --]
[-0.8728715609439694 -0.2182178902359922 -- 1.0910894511799623]
[-1.0910894511799614 -- 0.21821789023599275 0.8728715609439699]]
答案 1 :(得分:1)
直接对数据进行这种计算似乎是不可能的,因为data>0
掩码在data[data>0]
是1D的意义上不是保持形状的,而不是2D输入,这就是axis=1
掩码的原因。 1}}输入会导致错误。
在不使用任何循环的情况下实现此目的的最快方法可能是为np.nan
条目创建一个data<=0
值的新数据集,然后使用this SO response中的as。代码看起来像
masked_data = np.copy(data)
masked_data[masked_data>0] = np.nan
# Now use the nanmean and nanstd functions
z_score = x - scipy.stats.nanmean(masked_data)) / scipy.stats.nanstd(masked_data)
您需要自己添加正确的axis
命令,为清楚起见,我省略了这些命令,但这个想法基本相同。 nanmean
和nanstd
函数将忽略nan
值,同时保留数组的形状,以便可以正确地进行矢量化。