创建零大小二维numpy数组及解决追加子数组时的报错问题
解决Numpy数组追加图像块的问题
先理清楚你踩的坑:
初始数组创建错误:你用
numpy.array([], dtype=numpy.uint8)生成的是一维空数组(shape=(0,)),强行reshape成(28,28)根本不可能——空数组没有元素,没法拆成28×28的结构,这一步本身就有问题。而且你说[[]]没生成二维?不对,numpy.array([[]], dtype=numpy.uint8)是标准的二维空数组(shape=(1,0)),但这也不符合你要的28列的需求。第一次concatenate参数错误:
numpy.concatenate要求第一个参数是数组组成的序列(比如元组或列表),你直接传image, sub_image两个参数,相当于把第一个数组当轴来用,自然报索引错误。第二次维度不匹配错误:你初始的数组维度和子块不兼容——子块是(28,28),而你错误创建的数组要么是一维,要么是列数为0的二维,拼接时列数(axis=1)不一致,所以报错。
正确的实现方式:
方式一:先收集子块,最后一次性拼接(高效)
既然知道每次要加的是28×28的块,先把所有子块存在普通列表里,最后用concatenate一次性合并,避免多次内存复制:
import numpy as np # 初始化一个列表存子图像块 sub_blocks = [] # 模拟生成几个28×28的子块 for _ in range(5): sub_image = np.random.randint(0, 256, size=(28,28), dtype=np.uint8) sub_blocks.append(sub_image) # 一次性拼接成大数组(沿着行方向,最终shape是(140,28)) final_image = np.concatenate(sub_blocks, axis=0) # 如果是沿着列方向拼接,最终shape是(28,140) # final_image = np.concatenate(sub_blocks, axis=1)
方式二:动态追加(适合不确定子块数量的场景)
如果必须动态追加,先初始化一个列数为28的二维空数组,确保和子块的列数一致:
import numpy as np # 初始化二维空数组,shape=(0,28),和子块列数匹配 final_image = np.empty((0,28), dtype=np.uint8) # 模拟追加子块 for _ in range(3): sub_image = np.random.randint(0, 256, size=(28,28), dtype=np.uint8) # 沿着axis=0拼接,行增加 final_image = np.concatenate([final_image, sub_image], axis=0)
关于效率的补充
你说的没错,每次用concatenate都会重新分配内存并复制数据,频繁操作会很慢。所以优先用列表收集+一次性拼接的方式,或者如果能提前知道最终数组的大小(比如要加100个28×28的块,最终shape是(2800,28)),直接预先分配数组然后填充,效率更高:
import numpy as np # 预先分配数组,shape=(28*100,28) final_image = np.empty((2800,28), dtype=np.uint8) # 逐个填充子块 for i in range(100): sub_image = np.random.randint(0,256,size=(28,28),dtype=np.uint8) final_image[i*28 : (i+1)*28] = sub_image
内容的提问来源于stack exchange,提问作者user2138149
相关产品推荐
相关产品推荐

