Python 使用numpy布尔索引操作2D矩阵需要很长时间

Python 使用numpy布尔索引操作2D矩阵需要很长时间,python,numpy,optimization,numpy-ndarray,Python,Numpy,Optimization,Numpy Ndarray,我生成了大量随机数据,如下所示: ndata = np.random.binomial(1, 0.25, (100000, 1000)) 这是一个100000乘1000的矩阵(!) 我正在生成一个新的矩阵,其中对于每一行,每一列都是真的,如果所有列的平均值(减去贝努利RV的期望值,p=0.25)大于等于某个ε 像这样: def true_false_inequality(data, eps, data_len): return [abs(np.mean(data[:index + 1]

我生成了大量随机数据,如下所示:

ndata = np.random.binomial(1, 0.25, (100000, 1000))
这是一个100000乘1000的矩阵(!)

我正在生成一个新的矩阵,其中对于每一行,每一列都是真的,如果所有列的平均值(减去贝努利RV的期望值,p=0.25)大于等于某个ε

像这样:

def true_false_inequality(data, eps, data_len):
    return [abs(np.mean(data[:index + 1]) - 0.25) >= eps for index in range(data_len)]
这样做之后,我将生成一个1-d数组(最后!),其中每个列表示我在矩阵中的同一列中有多少个真值,然后我将每个列除以某个数字(exp_numer=100000)

另外,我有5个不同的ε,我从中迭代得到最终结果5次。 (ε=[0.001,0.1,0.5,0.25,0.025])

我的代码确实有效,但对于100000行乘1000列来说需要很长时间,我知道我可以通过稍微扩展numpy功能来加快速度,但我不知道如何操作。

你可以通过以下方法计算累积平均值:

np.cumsum(ndata, axis=0).sum(axis=1) / np.arange(1, 100001)
因此,我们可以优化
true\u false\u不等式

def true_false_inequality(data, eps, data_len):
    cummean = np.cumsum(ndata, axis=0).sum(axis=1) / np.arange(1, data_len)
    return abs(cummean - 0.25) >= eps
或者像@a_guest建议的那样,我们可以先对元素进行求和,然后计算累积和:

def true_false_inequality(data, eps, data_len):
    cummean = ndata.sum(axis=1).cumsum(axis=0) / np.arange(1, 100001)
    return abs(cummean - 0.25) >= eps

您可以在完整数据数组上使用矢量化操作执行整个计算:

mean = np.cumsum(data, axis=1) / np.arange(1, data.shape[1]+1)
condition = np.abs(mean - 0.25) >= eps
percentage = condition.sum(axis=0) / len(data)

看起来你是在用一个累加的平均值工作,对吗?@WillemVanOnsem true,但我想如果你暗示我应该这样做,那么使用np.mean()将等同于我自己这么做(?)如果您首先沿
轴=1求和,然后计算
求和
,这将更加优化,因为这样可以通过列计数减少所需的加法数量,并且类似地,从
求和
出来的临时数组所需的内存。但是在真-假不等式中,我计算单行的平均值!请注意,您访问了ndata,但该函数仅从大矩阵中的一行中获取数据参数。它不起作用,data.shape将始终为1,1000(在true_false_不等式函数中),请注意,我指定了每一行,如果之前所有列的平均值都是正确的,那么每个相应的列都是正确的。@MercyDude我误解了你的问题,请看我的更新答案,现在应该可以解决这个问题了。
mean = np.cumsum(data, axis=1) / np.arange(1, data.shape[1]+1)
condition = np.abs(mean - 0.25) >= eps
percentage = condition.sum(axis=0) / len(data)