以这种方式使用numpy数组不好吗?

2024-09-28 05:24:40 发布

您现在位置:Python中文网/ 问答频道 /正文

主要问题: 到处使用np.array([[1, 2, 3]])而不是np.array([1, 2, 3])是否不好(可能在计算时间或内存方面)

动机:

我有数学背景,所以我喜欢用向量和矩阵来思考问题。例如,我认为y = np.array([1, 2, 3])是行向量,或者是1 X 3矩阵。然而,numpy并不像对待1 X 3矩阵那样对待y。例如,如果我们取一个2x3的矩阵A = np.array([[1, 2, 3], [4, 5, 6]]),numpy将允许我们进行矩阵乘法A @ y,即使维数是(2x3)乘以(1x3)在数学上没有意义

另一方面,y @ A.T给出了一个错误,即使维度(1 X 3)乘以(3 X 2)是有意义的

因此,总之np.array([1, 2, 3])的行为并不完全像一个矩阵。然而,从我的实验来看,numpy似乎确实将np.array([[1, 2, 3]])视为真正的1 X 3矩阵。因此,如果没有缺点,我更愿意使用这个版本


Tags: 内存numpynp时间矩阵数学array向量
1条回答
网友
1楼 · 发布于 2024-09-28 05:24:40

numpy有一个旧的子类np.matrix,确保所有东西都有两个维度。但它不再被推荐

numpy尝试同样好地处理0、1、2和更多维度

In [69]: A = np.array([[1,2,3],[4,5,6]])
In [70]: x = np.array([1,2,3])
In [71]: y = np.array([[1,2,3]])
In [72]: A.shape
Out[72]: (2, 3)

a(2,3)与(3,)的矩阵积得到a(2,)。医生说它将(3,)展开为(3,1),得到(2,1)的结果,然后挤出1:

In [73]: A@x
Out[73]: array([14, 32])

带(1,3)转置的(2,3)产生(2,1):

In [74]: A@y.T
Out[74]: 
array([[14],
       [32]])

(3,)与(3,2)=>;(2,):

In [78]: x@A.T
Out[78]: array([14, 32])

(1,3)与(3,2)=>;(1,3):

In [79]: y@A.T
Out[79]: array([[14, 32]])

你的数学直觉如何处理3d或更高的阵列matmul/@处理得很好np.einsum做得更好


虽然您可以创建一个(1,n)数组,但前提是它能让您感觉更舒适。但请注意,您最终仍然会得到1甚至0d的结果

例如,使用索引:

In [80]: A
Out[80]: 
array([[1, 2, 3],
       [4, 5, 6]])
In [81]: A[1,:]
Out[81]: array([4, 5, 6])
In [82]: A[:,1]
Out[82]: array([2, 5])
In [83]: A[1,1]
Out[83]: 5
In [84]: A[1,1].shape
Out[84]: ()
In [85]: A[1,1].ndim
Out[85]: 0

或沿轴减小:

In [86]: A.sum(axis=1)
Out[86]: array([ 6, 15])

虽然可以保留尺寸:

In [87]: A.sum(axis=1, keepdims=True)
Out[87]: 
array([[ 6],
       [15]])
In [88]: A[[1],:]
Out[88]: array([[4, 5, 6]])
In [89]: A[:,[1]]
Out[89]: 
array([[2],
       [5]])

另一个需要记住的是,numpy操作符最适合操作元素。主要的异常是@。其中,在MATLAB中,A*B是矩阵乘法,A.*B是元素乘法。添加到broadcasting,这允许我们添加(2,3)和(3,)数组:

In [90]: A+x
Out[90]: 
array([[2, 4, 6],
       [5, 7, 9]])

这里(2,3)+(3,)=>;(2,3)+(1,3)=>;(2,3). 如果需要,(3,)1d数组通常表现为(1,3)甚至(1,1,3)。但另一个方向的扩张必须是明确的

In [92]: A / A.sum(axis=1)          # (2,3) with (2,) error
Traceback (most recent call last):
  File "<ipython-input-92-fec3395556f9>", line 1, in <module>
    A / A.sum(axis=1)
ValueError: operands could not be broadcast together with shapes (2,3) (2,) 

In [93]: A / A.sum(axis=1, keepdims=True)   # (2,3) with (2,1) ok
Out[93]: 
array([[0.16666667, 0.33333333, 0.5       ],
       [0.26666667, 0.33333333, 0.4       ]])
In [94]: A / A.sum(axis=1)[:,None]
Out[94]: 
array([[0.16666667, 0.33333333, 0.5       ],
       [0.26666667, 0.33333333, 0.4       ]])

相关问题 更多 >

    热门问题