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

2024-10-03 15:30:48 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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)

def final_res(data, eps):
    tf = np.array([true_false_inequality(data[seq], eps, data_len) for seq in range(exp_number)])
    percentage = tf.sum(axis=0)/exp_number
    return percentage

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

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


Tags: infalsetruefordataindexlenreturn
2条回答

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

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)

您可以使用以下公式计算累积平均值:

np.cumsum(ndata, axis=0).sum(axis=1) / np.arange(1, 100001)

因此,我们可以优化true_false_inequality以:

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

相关问题 更多 >