如何优雅拼接任意数量的numpy数组以构建特征矩阵?兼询numpy.concat与numpy.append的效果一致性
嘿,我来帮你搞定这个问题!你之前的循环写法确实有几个小问题,而且用numpy.concatenate才是这个场景下更优雅、高效的解决方案,我给你详细拆解一下:
先说说你原来循环写法的问题
你这段循环代码的问题出在enumerate的用法上:enumerate(value)返回的是**(索引, 数组元素)**的组合,不是你写的(subval, index),而且循环里试图拼接subval[index]和subval[index+1]不仅逻辑错误,还会在最后一次循环时出现索引越界的问题。
最优方案:用numpy.concatenate一步完成拼接
numpy.concatenate就是专门为多个数组的拼接设计的,完美适配数组数量不固定的场景,而且和你多次调用numpy.append的最终效果完全一致(其实numpy.append底层就是调用concatenate实现的,多次append相当于反复调用concatenate,效率更低)。
情况1:你的子数组已经是二维(可直接按列拼接)
如果你的每个子数组是二维结构(比如[[1,2,3]]这种形状为(1,3)的数组),直接传入数组列表和指定axis=1(按列拼接)即可:
import numpy as np value = [np.array([[1,2,3]]), np.array([[4,5,6]]), np.array([[7,8,9]]), np.array([[10,11,12]])] new_array = np.concatenate(value, axis=1) # 输出结果:[[ 1 2 3 4 5 6 7 8 9 10 11 12]]
情况2:你的子数组是一维(需要先转二维再拼接)
如果你的子数组是一维的(比如[1,2,3]这种形状为(3,)的数组),直接用axis=1拼接会报错(因为一维数组只有axis=0),需要先把每个一维数组转换成二维结构,再拼接:
import numpy as np value = [np.array([1,2,3]), np.array([4,5,6]), np.array([7,8,9]), np.array([10,11,12])] # 把每个一维数组转成(3,1)的二维数组 value_2d = [arr[:, np.newaxis] for arr in value] # 按列拼接 new_array = np.concatenate(value_2d, axis=1) # 输出结果: # [[ 1 4 7 10] # [ 2 5 8 11] # [ 3 6 9 12]]
如果你非要用循环(不推荐,但可以参考正确写法)
如果出于某种原因一定要用循环实现,正确的写法应该是先初始化结果为第一个数组,再依次拼接后续数组,避免索引错误和重复拼接:
import numpy as np value = [np.array([[1,2,3]]), np.array([[4,5,6]]), np.array([[7,8,9]]), np.array([[10,11,12]])] if not value: new_array = np.array([]) # 处理空列表的情况 else: new_array = value[0] for arr in value[1:]: new_array = np.append(new_array, arr, axis=1)
不过还是强烈推荐用concatenate,因为每次append都会创建新的数组对象,数组数量多的时候性能会差很多,而concatenate是一次性完成拼接,效率高得多。
内容的提问来源于stack exchange,提问作者dumbchild

