简单数组运算
参考numpy文件夹中的linalg.py获得更多信息。
import numpy
import numpy.linalg as linalg
a = numpy.array([
[1, 2],
[3, 4]
], dtype=float)
print("a: \n", a)
print("a的转置: \n", a.transpose())
print("a的你矩阵: \n", linalg.inv(a))
u = numpy.eye(2) # 2×2单位矩阵, eye = I
print("单位矩阵u: \n", u)
print("u的迹: \n", numpy.trace(u))
j = numpy.array([
[0, -1],
[1, 0]
], dtype=float)
print("j: \n", j)
print("j×j: \n", numpy.dot(j, j)) # 矩阵积
y = numpy.array([
[5],
[7]
], dtype=float)
print("y: \n", y)
print("线性方程求解: \n", linalg.solve(a, y))
print("特征向量求解: \n", linalg.eig(j))
"E:\Python 3.6.2\python.exe" F:/PycharmProjects/test.py
a:
[[ 1. 2.]
[ 3. 4.]]
a的转置:
[[ 1. 3.]
[ 2. 4.]]
a的你矩阵:
[[-2. 1. ]
[ 1.5 -0.5]]
单位矩阵u:
[[ 1. 0.]
[ 0. 1.]]
u的迹:
2.0
j:
[[ 0. -1.]
[ 1. 0.]]
j×j:
[[-1. 0.]
[ 0. -1.]]
y:
[[ 5.]
[ 7.]]
线性方程求解:
[[-3.]
[ 4.]]
特征向量求解:
(array([ 0.+1.j, 0.-1.j]), array([[ 0.70710678+0.j , 0.70710678-0.j ],
[ 0.00000000-0.70710678j, 0.00000000+0.70710678j]]))
Process finished with exit code 0
矩阵类
这是一个关于矩阵类的简短介绍。
import numpy
import numpy.linalg as linalg
a = numpy.matrix('1, 2; 3, 4', dtype=float)
print("a: \n", a)
print("TYPE a: ", type(a))
print("a的转置: \n", a.T)
x = numpy.matrix('5, 7', dtype=float).T
print("a×x: \n", a*x)
print("线性方程求解: \n", linalg.solve(a, x))
"E:\Python 3.6.2\python.exe" F:/PycharmProjects/test.py
a:
[[ 1. 2.]
[ 3. 4.]]
TYPE a: <class 'numpy.matrixlib.defmatrix.matrix'>
a的转置:
[[ 1. 3.]
[ 2. 4.]]
a×x:
[[ 19.]
[ 43.]]
线性方程求解:
[[-3.]
[ 4.]]
Process finished with exit code 0
索引:比较矩阵和二维数组
注意NumPy中数组和矩阵有些重要的区别。
NumPy提供了两个基本的对象:
一个N维数组对象和一个通用函数对象。其它对象都是建构在它们之上 的。
特别的,矩阵是继承自NumPy数组对象的二维数组对象。
对数组和矩阵,索引都必须包含合适的一个或多个这些组合:整数标量、省略号 (ellipses)、整数列表;布尔值,整数或布尔值构成的元组,和一个一维整数或布尔值数组。
矩阵可以被用作矩阵的索引,但是通常需要数组、列表或者 其它形式来完成这个任务。
像平常在Python中一样,索引是从0开始的。传统上我们用矩形的行和列表示一个二维数组或矩阵,其中沿着0轴的方向被穿过的称作行,沿着1轴的方向被穿过的是列。
import numpy
import numpy.linalg as linalg
# 创建数组和矩阵用来切片
A = numpy.arange(12)
print("A :", A)
A.shape = 3, 4
M = numpy.mat(A.copy()) # 深复制,转成矩阵
print("TYPE A: {}, TYPE M: {}".format(type(A), type(M)))
print("A: \n", A)
print("M: \n", M)
"E:\Python 3.6.2\python.exe" F:/PycharmProjects/test.py
A : [ 0 1 2 3 4 5 6 7 8 9 10 11]
TYPE A: <class 'numpy.ndarray'>, TYPE M: <class 'numpy.matrixlib.defmatrix.matrix'>
A:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
M:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
Process finished with exit code 0
基本的切片使用切片对象或整数。例如A[ : ]、M[ : ]的求值将表现得和Python索引很相似。然而要注意很重要的一点就是NumPy切片数组不创建数据的副本;切片提供统一数据的视图。
>>> print A[:]; print A[:].shape
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
(3, 4)
>>> print M[:]; print M[:].shape
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
(3, 4)
使用逗号分割索引来沿着多个轴索引。
import numpy
import numpy.linalg as linalg
# 创建数组和矩阵用来切片
A = numpy.arange(12)
print("A :", A)
A.shape = 3, 4
M = numpy.mat(A.copy()) # 深复制,转成矩阵
print("A: \n", A)
print("M: \n", M)
# 对二维数组使用一个冒号产生一个一维数组,然而矩阵产生了一个二维矩阵。
print("A[:, 1]: {} TYPE A[:, 1]: {}".format(A[:, 1], A[:, 1].shape))
print("M[:, 1]: \n {} TYPE M[:, 1]: {}".format(M[:, 1], M[:, 1].shape))
"E:\Python 3.6.2\python.exe" F:/PycharmProjects/test.py
A : [ 0 1 2 3 4 5 6 7 8 9 10 11]
TYPE A: <class 'numpy.ndarray'>, TYPE M: <class 'numpy.matrixlib.defmatrix.matrix'>
A:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
M:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
A[:, 1]: [1 5 9] TYPE A[:, 1]: (3,)
M[:, 1]:
[[1]
[5]
[9]] TYPE M[:, 1]: (3, 1)
Process finished with exit code 0
对二维数组使用一个冒号产生一个一维数组,然而矩阵产生了一个二维矩阵。10例如,一个M[2,:]
切片产生了一个形状为(1,4)的矩阵,相比之下,一个数组的切片总是产生一个最低可能维度11的数组。例如,如果C是一个三维数组,C[...,1]
产生一个二维的数组而C[1,:,1]
产生一个一维数组。从这时开始,如果相应的矩阵切片结果是相同的话,我们将只展示数组切片的结果。
import numpy
import numpy.linalg as linalg
# 创建数组和矩阵用来切片
A = numpy.arange(12)
print("A :", A)
A.shape = 3, 4
M = numpy.mat(A.copy()) # 深复制,转成矩阵
print("A: \n", A)
print("M: \n", M)
# 对二维数组使用一个冒号产生一个一维数组,然而矩阵产生了一个二维矩阵。
print("A[:, 1]: {} TYPE A[:, 1]: {}".format(A[:, 1], A[:, 1].shape)) # 切出的列
print("M[:, 1]: \n {} TYPE M[:, 1]: {}".format(M[:, 1], M[:, 1].shape))
print("A[1, :]: {} TYPE A[1, :]: {}".format(A[1, :], A[1, :].shape)) # 切出的行
print("M[1, :]: {} TYPE M[1, :]: {}".format(M[1, :], M[1, :].shape))
"E:\Python 3.6.2\python.exe" F:/PycharmProjects/test.py
A : [ 0 1 2 3 4 5 6 7 8 9 10 11]
A:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
M:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
A[:, 1]: [1 5 9] TYPE A[:, 1]: (3,)
M[:, 1]:
[[1]
[5]
[9]] TYPE M[:, 1]: (3, 1)
A[1, :]: [4 5 6 7] TYPE A[1, :]: (4,)
M[1, :]: [[4 5 6 7]] TYPE M[1, :]: (1, 4)
Process finished with exit code 0
数组的第一列和第三列,一种方法是使用列表切片:
# 切出第一列和第三列(从0开始计数)
print("M[:, [1, 3]]: {} TYPE M[:, [1, 3]]: {}".format(M[:, [1, 3]], M[:, [1, 3]].shape))
M[:, [1, 3]]: [[ 1 3]
[ 5 7]
[ 9 11]] TYPE M[:, [1, 3]]: (3, 2)
稍微复杂点的方法是使用 take() 方法(method):
print("M[:, [1, 3]]:", M[:, ].take([1, 3], axis=1))
如果我们想跳过第一行,我们可以这样:
# 跳过第一行
print("跳过A的第一行进行切片: ", A[1:, ].take([1, 3], axis=1))
# 跳过第一行,矩阵向量积实现
print("跳过A的第一行进行切片: ", A[numpy.ix_((1, 2), (1, 3))])
跳过A的第一行进行切片: [[ 5 7]
[ 9 11]]
跳过A的第一行进行切片: [[ 5 7]
[ 9 11]]
现在让我们做些更复杂的。比如说我们想要保留第一行大于1的列。一种方法是创建布尔索引:
>>> A[0,:]>1
array([False, False, True, True], dtype=bool)
>>> A[:,A[0,:]>1]
array([[ 2, 3],
[ 6, 7],
[10, 11]])
但是索引矩阵没这么方便,它只会计算第一行。
>>> M[0,:]>1
matrix([[False, False, True, True]], dtype=bool)
>>> M[:,M[0,:]>1]
matrix([[2, 3]]) # 不知道为什么报错,IndexError: too many indices for array
这个过程的问题是用“矩阵切片”来切片产生一个矩阵,但是矩阵有A属性,它的值是数组呈现的。所以我们仅仅做以下替代:
>>> M[:,M.A[0,:]>1]
matrix([[ 2, 3],
[ 6, 7],
[10, 11]])
如果我们想要在矩阵两个方向有条件地切片,我们必须稍微调整策略,代之以:
>>> A[A[:,0]>2,A[0,:]>1] # 只取结果矩阵的对角线
array([ 6, 11])
>>> M[M.A[:,0]>2,M.A[0,:]>1]
matrix([[ 6, 11]])
我们需要使用向量积ix_():
>>> A[ix_(A[:,0]>2,A[0,:]>1)]
array([[ 6, 7],
[10, 11]])
>>> M[ix_(M.A[:,0]>2,M.A[0,:]>1)]
matrix([[ 6, 7],
[10, 11]])
print(A[numpy.ix_(A[:, 0] > 2, A[0, :] > 1)]) # 等价于A[A[:, 0] > 2, :][:, A[0, :] > 1]
来源:oschina
链接:https://my.oschina.net/u/3647649/blog/1806209