基于Python Numpy的数组array和矩阵matrix详解

本文详细介绍了NumPy中的核心对象——数组array和矩阵matrix,包括它们的创建、区别、属性和常见操作。重点讲解了数组的秩、形状、大小和数据类型,以及数组和矩阵的基本运算、索引、切片和迭代。同时,文章讨论了NumPy中的广播法则和线性代数操作,揭示了NumPy在数值计算中的灵活性和高效性。
摘要由CSDN通过智能技术生成

NumPy的主要对象是同种元素的多维数组。这是一个所有的元素都是一种类型、通过一个正整数元组索引的元素表格(通常是元素是数字)。

在NumPy中维度(dimensions)叫做轴(axes),轴的个数叫做秩(rank,但是和线性代数中的秩不是一样的,在用python求线代中的秩中,我们用numpy包中的linalg.matrix_rank方法计算矩阵的秩,例子如下)。

结果是:

线性代数中秩的定义:设在矩阵A中有一个不等于0的r阶子式D,且所有r+1阶子式(如果存在的话)全等于0,那末D称为矩阵A的最高阶非零子式,数r称为矩阵A的秩,记作R(A)。

numpy中数组和矩阵的区别:

matrix是array的分支,matrix和array在很多时候都是通用的,你用哪一个都一样。但这时候,官方建议大家如果两个可以通用,那就选择array,因为array更灵活,速度更快,很多人把二维的array也翻译成矩阵。

但是matrix的优势就是相对简单的运算符号,比如两个矩阵相乘,就是用符号*,但是array相乘不能这么用,得用方法.dot()

array的优势就是不仅仅表示二维,还能表示3、4、5…维,而且在大部分Python程序里,array也是更常用的。

现在我们讨论numpy的多维数组

例如,在3D空间一个点的坐标[1, 2,
3]是一个秩为1的数组,因为它只有一个轴。那个轴长度为3.又例如,在以下例子中,数组的秩为2(它有两个维度).第一个维度长度为2,第二个维度长度为3.

    [[ 1., 0., 0.],
     [ 0., 1., 2.]] 

NumPy的数组类被称作ndarray。通常被称作数组。注意numpy.array和标准Python库类array.array并不相同,后者只处理一维数组和提供少量功能。更多重要ndarray对象属性有:

ndarray.ndim

数组轴的个数,在python的世界中,轴的个数被称作秩

ndarray.shape

数组的维度。这是一个指示数组在每个维度上大小的整数元组。例如一个n排m列的矩阵,它的shape属性将是(2,3),这个元组的长度显然是秩,即维度或者ndim属性

ndarray.size

数组元素的总个数,等于shape属性中元组元素的乘积。

ndarray.dtype

一个用来描述数组中元素类型的对象,可以通过创造或指定dtype使用标准Python类型。另外NumPy提供它自己的数据类型。

ndarray.itemsize

数组中每个元素的字节大小。例如,一个元素类型为float64的数组itemsiz属性值为8(=64/8),又如,一个元素类型为complex32的数组item属性为4(=32/8).

ndarray.data

包含实际数组元素的缓冲区,通常我们不需要使用这个属性,因为我们总是通过索引来使用数组中的元素。

一个例子1

    >>> from numpy import *
    >>> a = arange(15).reshape(3, 5)
    >>> a
    array([[ 0, 1, 2, 3, 4],
     [ 5, 6, 7, 8, 9],
     [10, 11, 12, 13, 14]])
    >>> a.shape
    (3, 5)
    >>> a.ndim
    2
    >>> a.dtype.name
    'int32'
    >>> a.itemsize
    4
    >>> a.size
    15
    >>> type(a)
    numpy.ndarray
    >>> b = array([6, 7, 8])
    >>> b
    array([6, 7, 8])
    >>> type(b)
    numpy.ndarray 

创建数组

有好几种创建数组的方法。

例如,你可以使用array函数从常规的Python列表和元组创造数组。所创建的数组类型由原序列中的元素类型推导而来。

    >>> from numpy import *
    >>> a = array( [2,3,4] )
    >>> a
    array([2, 3, 4])
    >>> a.dtype
    dtype('int32')
    >>> b = array([1.2, 3.5, 5.1])
    >>> b.dtype
    dtype('float64') 

一个常见的错误包括用多个数值参数调用array而不是提供一个由数值组成的列表作为一个参数。

    >>> a = array(1,2,3,4) # WRONG
    >>> a = array([1,2,3,4]) # RIGHT 
    

数组将序列包含序列转化成二维的数组,序列包含序列包含序列转化成三维数组等等。

    >>> b = array( [ (1.5,2,3), (4,5,6) ] )
    >>> b
    array([[ 1.5, 2. , 3. ],
     [ 4. , 5. , 6. ]]) 

数组类型可以在创建时显示指定

    >>> c = array( [ [1,2], [3,4] ], dtype=complex )
    >>> c
    array([[ 1.+0.j, 2.+0.j],
     [ 3.+0.j, 4.+0.j]]) 

通常,数组的元素开始都是未知的,但是它的大小已知。因此,NumPy提供了一些使用占位符创建数组的函数。这最小化了扩展数组的需要和高昂的运算代价。

函数function创建一个全是0的数组,函数ones创建一个全1的数组,函数empty创建一个内容随机并且依赖与内存状态的数组。默认创建的数组类型(dtype)都是float64。

    >>> zeros( (3,4) )
    array([[0., 0., 0., 0.],
     [0., 0., 0., 0.],
     [0., 0., 0., 0.]])
    >>> ones( (2,3,4), dtype=int16 )  # dtype can also be specified
    array([[[ 1, 1, 1, 1],
     [ 1, 1, 1, 1],
     [ 1, 1, 1, 1]],
     [[ 1, 1, 1, 1],
     [ 1, 1, 1, 1],
     [ 1, 1, 1, 1]]], dtype=int16)
    >>> empty( (2,3) )
    array([[ 3.73603959e-262, 6.02658058e-154, 6.55490914e-260],
     [ 5.30498948e-313, 3.14673309e-307, 1.00000000e+000]]) 

为了创建一个数列,NumPy提供一个类似arange的函数返回数组而不是列表:

    >>> arange( 10, 30, 5 )
    array([10, 15, 20, 25])
    >>> arange( 0, 2, 0.3 )   # it accepts float arguments
    array([ 0. , 0.3, 0.6, 0.9, 1.2, 1.5, 1.8]) 

当arange使用浮点数参数时,由于有限的浮点数精度,通常无法预测获得的元素个数。因此,最好使用函数linspace去接收我们想要的元素个数来代替用range来指定步长。

其它函数array, zeros, zeros_like, ones, ones_like, empty, empty_like, arange,
linspace, rand, randn, fromfunction, fromfile参考: [ NumPy示例

](https://docs.scipy.org/doc/numpy/reference/routines.html)

打印数组

当你打印一个数组,NumPy以类似嵌套列表的形式显示它,但是呈以下布局:

最后的轴从左到右打印

次后的轴从顶向下打印

剩下的轴从顶向下打印,每个切片通过一个空行与下一个隔开

一维数组被打印成行,二维数组成矩阵,三维数组成矩阵列表。

    >>> a = arange(6)    # 1d array
    >>> print a
    [0 1 2 3 4 5]
    >>>
    >>> b = arange(12).reshape(4,3)  # 2d array
    >>> print b
    [[ 0 1 2]
     [ 3 4 5]
     [ 6 7 8]
     [ 9 10 11]]
    >>>
    >>> c = arange(24).reshape(2,3,4)  # 3d array
    >>> print c
    [[[ 0 1 2 3]
     [ 4 5 6 7]
     [ 8 9 10 11]]
     [[12 13 14 15]
     [16 17 18 19]
     [20 21 22 23]]] 
    

查看形状操作一节获得有关reshape的更多细节

如果一个数组用来打印太大了,NumPy自动省略中间部分而只打印角落

    >>> print arange(10000)
    [ 0 1 2 ..., 9997 9998 9999]
    >>>
    >>> print arange(10000).reshape(100,100)
    [[ 0 1 2 ..., 97 98 99]
     [ 100 101 102 ..., 197 198 199]
     [ 200 201 202 ..., 297 298 299]
     ...,
     [9700 9701 9702 ..., 9797 9798 9799]
     [9800 9801 9802 ..., 9897 9898 9899]
     [9900 9901 9902 ..., 9997 9998 9999]] 

禁用NumPy的这种行为并强制打印整个数组,你可以设置printoptions参数来更改打印选项。

    >>> set_printoptions(threshold='nan') 

基本运算

数组的算术运算是按元素的。新的数组被创建并且被结果填充。

    >>> a = array( [20,30,40,50] )
    >>> b = arange( 4 )
    >>> b
    array([0, 1, 2, 3])
    >>> c = a-b
    >>> c
    array([20, 29, 38, 47])
    >>> b**2
    array([0, 1, 4, 9])
    >>> 10*sin(a)
    array([ 9.12945251, -9.88031624, 7.4511316 , -2.62374854])
    >>> a<35
    array([True, True, False, False], dtype=bool) 

不像许多矩阵语言,NumPy中的乘法运算符*指示按元素计算,矩阵乘法可以使用dot函数或创建矩阵对象实现(参见教程中的矩阵章节)

    >>> A = array( [[1,1],
    ...  [0,1]] )
    >>> B = array( [[2,0],
    ...  [3,4]] )
    >>> A*B    # elementwise product
    array([[2, 0],
     [0, 4]])
    >>> dot(A,B)   # matrix product
    array([[5, 4],
     [3, 4]]) 

有些操作符像+=和*=被用来更改已存在数组而不创建一个新的数组。

    >>> a = ones((2,3), dtype=int)
    >>> b = random.random((2,3))
    >>> a *= 3
    >>> a
    array([[3, 3, 3],
     [3, 3, 3]])
    >>> b += a
    >>> b
    array([[ 3.69092703, 3.8324276 , 3.0114541 ],
     [ 3.18679111, 3.3039349 , 3.37600289]])
    >>> a += b     # b is converted to integer type
    >>> a
    array([[6, 6, 6],
     [6, 6, 6]]) 

当运算的是不同类型的数组时,结果数组和更普遍和精确的已知(这种行为叫做upcast)。

    >>> a = ones(3, dtype=int32)
    >>> b = linspace(0,pi,3)
    >>> b.dtype.name
    'float64'
    >>> c = a+b
    >>> c
    array([ 1. , 2.57079633, 4.14159265])
    >>> c.dtype.name
    'float64'
    >>> d = exp(c*1j)
    >>> d
    array([ 0.54030231+0.84147098j, -0.84147098+0.54030231j,
     -0.54030231-0.84147098j])
    >>> d.dtype.name
    'complex128' 

许多非数组运算,如计算数组所有元素之和,被作为ndarray类的方法实现

    >>> a = random.random((2,3))
    >>> a
    array([[ 0.6903007 , 0.39168346, 0.16524769],
     [ 0.48819875, 0.77188505, 0.94792155]])
    >>> a.sum()
    3.4552372100521485
    >>> a.min()
    0.16524768654743593
    >>> a.max()
    0.9479215542670073 

这些运算默认应用到数组好像它就是一个数字组成的列表,无关数组的形状。然而,指定axis参数你可以吧运算应用到数组指定的轴上:

    >>> b = arange(12).reshape(3,4)
    >>>
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值