在 NumPy 中使用拼接向量化 for 循环

Vectorizing for loop using splicing in NumPy

我有这个 for 循环:

blockSize = 5
ds = np.arange(20)
ds = np.reshape(ds, (1, len(ds))
counts = np.zeros(len(ds[0]/blockSize))

for i in range(len(counts[0])):
    counts[0, i] = np.floor(np.sum(ds[0, i*blockSize:i*blockSize+blockSize]))

我正在尝试对其进行矢量化,做这样的事情:

countIndices = np.arange(len(counts[0]))
counts[0, countsIndices] = np.floor(np.sum(ds[0, countIndices*blockSize:countIndices*blockSize + blockSize]))

但是,这不起作用并出现此错误:

counts[0, countIndices] = np.floor(np.sum(ds[0, countIndices*blockSize:countIndices*blockSize + blockSize]))
TypeError: only integer scalar arrays can be converted to a scalar index

我知道类似这样的方法有效:

counts[0, countIndices] = np.floor(ds[0, countIndices*blockSize]
                         + ds[0, countIndices*blockSize + 2] +
                         ... ds[0, countIndices*blockSize + blockSize])

问题是对于较大的块大小值(在我的实际代码中块大小非常大),这是不可行的。我对如何完成我想要的感到困惑。非常感谢任何帮助。

如果将结果存储到整数数组,则无需执行 floor。您还可以创建一个大小为 blockSize 的假新轴来完全矢量化您的操作。

block_size = 5
ds = np.arange(80.0).reshape(4, -1)   # Shape (4, 20)
counts = np.empty((ds.shape[0], ds.shape[1] // block_size), dtype=int)

引入伪维度和求和:

ds.reshape(ds.shape[0], -1, block_size).sum(axis=-1, out=counts)

重塑不复制数据,因此操作ds.reshape(ds.shape[0], -1, block_size)在时间和space上都非常便宜。

您可以对其中一个整形维度使用 -1 以避免 computing/writing 长除法表达式。