如何在numpy.ndarray对象的子集上应用函数

时间:2015-02-13 18:56:46

标签: python numpy

我有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)

2 个答案:

答案 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命令,为清楚起见,我省略了这些命令,但这个想法基本相同。 nanmeannanstd函数将忽略nan值,同时保留数组的形状,以便可以正确地进行矢量化。