numpy 1D数组遵循行/列规则吗?

时间:2016-02-07 10:38:42

标签: python arrays numpy

我刚开始使用numpy,我对如何使用数组感到困惑。我已经在numpy数组上看到了几个Stack Overflow的答案,但它们都处理了如何获得所需的结果(我知道如何做到这一点,我只是不知道为什么我需要这样做)。我见过的共识是数组比矩阵更好,因为它们是一个更基本的类,限制性更小。我知道你可以转置一个数组,这意味着行和列之间有区别,但乘法规则都会产生错误的输出(与我期望的相比)。

以下是我与输出一起编写的测试代码:

a = numpy.array([1,2,3,4])
print(a)
>>> [1 2 3 4]

print(a.T)          # Transpose
>>> [1 2 3 4]       # No apparent affect

b = numpy.array( [ [1], [2], [3], [4] ] )
print(b)
>>> [[1]
     [2]
     [3]
     [4]]           # Column (Expected)

print(b.T)
>>> [[1 2 3 4]]     # Row (Expected, transpose seems to work here)

print((b.T).T)
>>> [[1]
     [2]
     [3]
     [4]]           # Column (All of these are as expected, 
                    #          unlike for declaring the array as a row vector)

# The following are element wise multiplications of a
print(a*a)
>>> [ 1  4  9 16]

print(a * a.T)      # Row*Column
>>> [ 1  4  9 16]   # Inner product scalar result expected

print(a.T * a)      # Column*Row
>>> [ 1  4  9 16]   # Outer product matrix result expected

print(b*b)
>>> [[1]
     [4]
     [9]
     [16]]          # Expected result, element wise multiplication in a column

print(b * b.T)      # Column * Row (Outer product)
>>> [[ 1  2  3  4]
     [ 2  4  6  8]
     [ 3  6  9 12]
     [ 4  8 12 16]] # Expected matrix result

print(b.T * (b.T))  # Column * Column (Doesn't make much sense so I expected elementwise multiplication
>>> [[ 1  4  9 16]]

print(b.T * (b.T).T) # Row * Column, inner product expected
>>> [[ 1  2  3  4]
    [ 2  4  6  8]
    [ 3  6  9 12]
    [ 4  8 12 16]]  # Outer product result

我知道我可以使用numpy.inner()numpy.outer()来实现效果(这不是问题),我只是想知道我是否需要跟踪我的向量是行还是列。

我也知道我可以创建一个1D矩阵来表示我的向量,并且乘法按预期工作。我正在尝试找出存储数据的最佳方法,这样当我查看我的代码时,很明显会发生什么 - 现在数学看起来很混乱和错误。

我只需要为我的应用程序使用1D和2D张量。

3 个答案:

答案 0 :(得分:5)

我会尝试注释你的代码

a = numpy.array([1,2,3,4])
print(a)
>>> [1 2 3 4]

print(a.T)          # Transpose
>>> [1 2 3 4]       # No apparent affect

a.shape会显示(4,)a.T.shape是一样的。它保持相同数量的维度,并执行唯一有意义的转置 - 没有变化。使其成为(4,1)会增加维度,并销毁A.T.T往返。

b = numpy.array( [ [1], [2], [3], [4] ] )
print(b)
>>> [[1]
     [2]
     [3]
     [4]]           # Column (Expected)

print(b.T)
>>> [[1 2 3 4]]     # Row (Expected, transpose seems to work here)

b.shape(4,1)b.T.shape(1,4)。注意额外的[]集。如果您将a创建为a = numpy.array([[1,2,3,4]]),其形状也可能是(1,4)

b的简单方法是b=np.array([[1,2,3,4]]).T(或b=np.array([1,2,3,4])[:,None]b=np.array([1,2,3,4]).reshape(-1,1)

将其与MATLAB进行比较

octave:3> a=[1,2,3,4]
a =
   1   2   3   4
octave:4> size(a)
ans =
   1   4
octave:5> size(a.')
ans =
   4   1

即使没有额外的[],它也会将矩阵初始化为2d。

numpy有一个模仿MATLAB的matrix类 - 在MATLAB只允许2d的时候。

In [75]: m=np.matrix('1 2 3 4')

在[76]中:m     Out [76]:矩阵([[1,2,3,4]])

In [77]: m.shape
Out[77]: (1, 4)

In [78]: m=np.matrix('1 2; 3 4')

In [79]: m
Out[79]: 
matrix([[1, 2],
        [3, 4]])

我不建议使用np.matrix,除非它确实为您的代码添加了一些有用的东西。

请注意MATLAB对vectors的讨论,但它们实际上只是matrix只有一个非单一维度。

# The following are element wise multiplications of a
print(a*a)
>>> [ 1  4  9 16]

print(a * a.T)      # Row*Column
>>> [ 1  4  9 16]   # Inner product scalar result expected

此行为遵循a.T == A。如您所述,*逐个元素生成。这相当于MATLAB .*np.dot(a,a)给出了2个数组的点或矩阵乘积。

print(a.T * a)      # Column*Row
>>> [ 1  4  9 16]   # Outer product matrix result expected

不,它仍在进行元素乘法。

我会使用broadcastinga[:,None]*a[None,:]来获取外部产品。 Octave在模仿numpy时添加了这个;我不知道MATLAB是否还有。

以下*始终是逐元素乘法。它的广播产生矩阵/外部产品结果。

print(b*b)
>>> [[1]
     [4]
     [9]
     [16]]          # Expected result, element wise multiplication in a column

A (4,1) * (4,1)=>(4,1)。周围的形状相同。

print(b * b.T)      # Column * Row (Outer product)
>>> [[ 1  2  3  4]
     [ 2  4  6  8]
     [ 3  6  9 12]
     [ 4  8 12 16]] # Expected matrix result

此处(4,1)*(1,4)=>(4,4)产品。已复制了2个尺寸1尺寸,因此它实际上变为(4,4)*(4,4)。你会如何在MATLAB中复制它 - 使用.*

print(b.T * (b.T))  # Column * Column (Doesn't make much sense so I expected elementwise multiplication
>>> [[ 1  4  9 16]]
无论期望如何,

*都是元素。在MATLAB中思考b' .* b'

print(b.T * (b.T).T) # Row * Column, inner product expected
>>> [[ 1  2  3  4]
    [ 2  4  6  8]
    [ 3  6  9 12]
    [ 4  8 12 16]]  # Outer product result

再次*是元素; inner除了乘法之外还需要求和。这里广播再次适用(1,4)*(4,1)=>(4,4)

np.dot(b,b)np.trace(b.T*b)np.sum(b*b)提供30

当我在MATLAB中工作时,我经常检查size,并创建可以捕获尺寸不匹配的测试矩阵(例如2x3而不是2x2矩阵)。我继续在numpy中做到这一点。

关键是:

  • numpy数组可能是1d(甚至是0d)

  • A(4,)数组与(4,1)或(1,4)`不完全相同。

  • *是元素 - 永远。

  • 广播通常会占用outer行为

答案 1 :(得分:3)

从一个笨拙的角度来看,“转置”对于二维结构来说真的只是一个有意义的概念:

>>> import numpy
>>> arr = numpy.array([1,2,3,4])
>>> arr.shape
(4,)
>>> arr.transpose().shape
(4,)

所以,如果你想要转置某些内容,你必须使它成为二维的:

>>> arr_2d = arr.reshape((4,1)) ## four rows, one column -> two-dimensional
>>> arr_2d.shape
(4, 1)
>>> arr_2d.transpose().shape
(1, 4)

此外,numpy.array(iterable, **kwargs)还有一个关键字参数ndmin,设置为ndmin=2,并根据需要添加1所需的形状:

>>> arr_ndmin = numpy.array([1,2,3,4],ndmin=2)
>>> arr_ndmin.shape
(1, 4)

答案 2 :(得分:2)

是的,他们这样做。

您的问题已经回答了。虽然我假设你是Matlab用户?如果是这样,您可能会发现本指南很有用:Moving from MATLAB matrices to NumPy arrays