问题描述
我有一个数组,例如arr = [1,2,3,4]
和 m = 3
。我想用 m
行制作一个矩阵,重复该数组。该示例的输出将是
[[1,4],[1,4]]
我该怎么做?我试过
np.vstack((arr,arr,arr))
然而,据我所知,这只有在我有效地硬核 m
时才有效。
解决方法
numpy 中有许多选项:
-
最简单的是
np.stack
,新轴设置为0:result = np.stack((arr,) * m,axis=0)
这是
np.vstack
的推广,它可以以同样的方式接受变量m
:result = np.vstack((arr,) * m)
-
由于您希望扩展第一个维度而不是第二个维度,您可以使用
np.tile
:result = np.tile(arr,[m,1])
-
对于这种简单的情况,您可以使用
np.repeat
单独重复元素以获得相同的结果。这有点hacky,但它也能正常工作:result = np.repeat([arr],m,axis=0)
如果
arr
已经是一个 numpy 数组,您可以更明确地添加前导维度:result = np.repeat(arr[None,:],axis=0)
-
使用
np.concatenate
是一种稍微复杂的方法,但它更好地展示了幕后发生的事情:np.concatenate(([arr],axis=0)
-
本着与
concatenate
相同的精神,您可以直接使用构造函数np.array
:np.array([arr] * m)
-
一个丑陋的方法是使用乘法(结合广播):
result = arr * np.ones((m,1),dtype=np.int8)
将 dtype 设置为非常小的整数类型几乎可以确保结果将提升为数组的实际类型。
-
之前的方法多次复制数组以获取二维数据。但由于数据是重复的,您实际上不需要复制它。相反,您可以使用 broadcasting 创建一个创建假第一维的视图。具体来说,
np.broadcast_to
函数将完全按照您的要求执行操作:result = np.broadcast_to(arr,len(arr)])
-
有一种比之前更通用的方法来创建视图是
np.lib.stride_tricks.as_strided
。首先,让我们重申文档中的警告:
警告
必须非常小心地使用此功能,请参阅注释。
除非您提前知道计划使用的 dtype 的字节大小,否则最好确保
arr
是一个 numpy 数组以从中获取步幅:arr = np.asanyarray(arr) result = np.lib.stride_tricks.as_strided(arr,shape=(m,arr.size),strides=(0,) + arr.strides)
在后两种情况下,如果您想将视图扩展为包含每个元素的适当副本的完整缓冲区,您可以copy 数据:
result = result.copy()
如果您不进行扩展,您将有效地模拟对同一列表的多个引用的行为,其中修改任何元素都会更改同一列中的所有元素。
,您可以使用:
import numpy as np
arr,m = [1,2,3,4],3
np.vstack([arr]*m)
输出:
array([[1,[1,4]])
另一方面,为什么需要创建这样的矩阵?您可能正在寻找 numpy broadcasting 而无需重复您的数组。
,你可以这样做:
n = [1,4]
m = 3
i = 0;
array = []
while(i<m):
array.append(n)
i+=1
print(array)
=> [[1,4]]