沿轴合并 Python 数组

问题描述 投票:0回答:2

我一直在尝试填充用于 Keras 模型的训练数据集。使用 numpy 的

append
函数一切 works 都很好,但是它 非常慢。这是我现在正在做的事情:

def populateData():
    images = np.zeros([1, 4, 512, 512, 6])
    for m in range(2):
        for n in range(4):
            batch_np = np.zeros([4, 512, 512, 6])

            # Doing stuff with the batch...
            # ...

            images = np.append(images, batch_np, axis=0)

随着数组的大小随着每次传递而增长,numpy 附加新数据所花费的时间几乎呈指数增长。因此,例如,第一次传递大约需要 1 秒,第三次传递只需 3 秒多一点。当我完成十几个或更多的时候,每个

append
操作需要很多minutes(!)。根据目前的进度,可能需要几天才能完成。

我希望能够在下一个冰河时代之前的某个时间填充我的训练数据集。除了“获得更好的硬件”之外,我能做些什么来加速

np.append(...)
?我的理解是 Numpy 的
append
函数每次调用此函数时都会复制整个数组。是否有一个等价的函数 not 每次都执行复制?还是改用参考值,然后修改它?

我尝试使用 Python 的内置

list append
函数重写其中的一些内容,但它不像 numpy 的附加函数那样提供
axis
支持。因此,虽然这看起来快得多,但它对于这种多维设置并不适用。


TL;DR:有没有办法在附加到 Python 列表时指定轴?如果没有,是否有更优化的方法沿指定轴附加到 N 维数组/加速

numpy.append

python arrays numpy multidimensional-array append
2个回答
1
投票

您可以使用

np.stack
并使用 python 列表:

images = []
for m in range(2):
    for n in range(4):
        batch_np = np.zeros([4, 512, 512, 6])
        ...
        images.append(batch_np)
images = np.stack(images, axis=0)

输出:

>>> images.shape
(8, 4, 512, 512, 6)

或者在循环之前分配整个数组:

M = 2
N = 4
images = np.zeros([M*N, N, 512, 512, 6])
for i, m in enumerate(range(M)):
    for j, n in enumerate(range(N)):
        batch_np = np.zeros([N, 512, 512, 6])
        images[i+j] = batch_np

输出:

>>> images.shape
(8, 4, 512, 512, 6)

0
投票

为什么你需要指定一个带有列表追加的轴?这两个循环产生相同的形状:

In [62]: arr = np.zeros([0,3,4])
    ...: for i in range(5):
    ...:     arr = np.append(arr, np.ones((1,3,4)), axis=0)
    ...: arr.shape
Out[62]: (5, 3, 4)

In [63]: alist = []
    ...: for i in range(5):
    ...:     alist.append(np.ones((3,4)))
    ...: arr = np.array(alist)    
In [64]: arr.shape
Out[64]: (5, 3, 4)

stack
与默认轴 0 做同样的事情:

In [65]: np.stack(alist, axis=0).shape
Out[65]: (5, 3, 4)
In [66]: np.stack(alist, axis=1).shape
Out[66]: (3, 5, 4)
© www.soinside.com 2019 - 2024. All rights reserved.