>>> np.hstack([np.array([1, 2, 3]), np.array([4, 5, 6])])
array([1, 2, 3, 4, 5, 6])
>>> np.column_stack([np.array([1, 2, 3]), np.array([4, 5, 6])])
array([[1, 4],
[2, 5],
[3, 6]])
当然对等地,也存在,np.vstack, np.row_stack
>>> np.vstack([np.array([1, 2, 3]), np.array([4, 5, 6])])
array([[1, 2, 3],
[4, 5, 6]])
>>> np.row_stack([np.array([1, 2, 3]), np.array([4, 5, 6])])
array([[1, 2, 3],
[4, 5, 6]])
# 两者近乎等效
首先一点,不管二者处理的是不是对称阵,两者处理的首先是方阵(square array)。
两者均用于矩阵特征分解,np.linalg.eigh()适用于对称矩阵,可见矩阵分析中针对对称矩阵的特征值分解有一套特殊的不同于一般矩阵的理论。
def main():
X = np.random.randn(3, 3)
X = X.triu()
X += (X.T-np.diag(X.diagonal()))
# 构造对称矩阵 X
Lambda1, Q1 = np.linalg.eig(X)
Lambda2, Q2 = np.linalg.eigh(X)
print(Lambda1)
# [ 1.53176315 -0.35907022 -1.8924684 ]
# 排序不太严格
print(Lambda2)
# [-1.8924684 -0.35907022 1.53176315]
# 严格的升序
if __name__ == '__main__':
main()
形式上array.T自然比array.transpose()这样一个函数调用形式稍显简洁。
>>> x = np.ones((3, 4))
>>> x.T
array([[ 1., 1., 1.],
[ 1., 1., 1.],
[ 1., 1., 1.],
[ 1., 1., 1.]])
>>> x.transpose()
array([[ 1., 1., 1.],
[ 1., 1., 1.],
[ 1., 1., 1.],
[ 1., 1., 1.]])
事实上,x.T == x.transpose(range(x.ndim)[::-1])
>>> x.transpose(range(x.ndim)[::-1])
array([[ 1., 1., 1.],
[ 1., 1., 1.],
[ 1., 1., 1.],
[ 1., 1., 1.]])
np.triu:upper triangle of an array
np.tril:lower triangle of an array
>>> x = np.array([[1, 2, 3], [3, 4, 5], [5, 6, 7], [7, 8, 9]])
>>> x
array([[1, 2, 3],
[3, 4, 5],
[5, 6, 7],
[7, 8, 9]])
>>> np.triu(x)
array([[1, 2, 3],
[0, 4, 5],
[0, 0, 7],
[0, 0, 0]])
>>> np.tril(x)
array([[1, 0, 0],
[3, 4, 0],
[5, 6, 7],
[7, 8, 9]])
注意,要进行拼接的数组都是以tuple_like((a, b))
的形式传递给这三个函数的,
np.concatenate((a, b), axis=0) == np.vstack((a, b))
# 也对应于默认的情况,np.concatenate((a, b))
np.concatenate((a, b), axis=1) == np.hstack((a, b))