天天看点

Numpy多维数组的介绍及其常用属性和操作方法1、什么是Numpy?2、ndarray介绍3、数组运算

1、什么是Numpy?

Numpy是Python中科学计算的基础软件包。

它提供多维数组对象、多种派生对象(如掩码数组、矩阵)以及用于快速操作数组的函数,包括数学、逻辑、数组形状变换、排序、选择、统计运算等等。

Numpy包的核心是

ndarray

对象。

它封装了python原生的同数据类型的n维数组,为了保证其性能优良,其中许多操作都是在本地编译后代码中执行的。

Numpy数组相比python内置序列主要区别如下:

  • Numpy数组在创建时固定大小,更改ndarray的大小将创建一个新数组并销毁原数组;
  • Numpy数组元素具有相同数据类型,占用相同内存;
  • Numpy数组有助于对大量数据高效地完成高级数学运算和其他类型操作;

对于涉及

ndarray

对象的算术、逻辑、位运算等,Numpy默认执行预编译的C代码对逐个元素操作,如:

c = a * b
           

上式中,若a和b是形状相同的多维数组 ,或是一个标量和一个多维数组,甚至是两个不同形状的数组(较小数组可通过某种方式扩展到较大数组),Numpy对其均是逐个元素操作。这说明了Numpy的两个特征:

矢量化

广播

。矢量化指代码中无任何显式的循环、索引等,这些事情在优化的、预编译的C代码中完成。广播指隐式地对元素逐个操作的术语。

2、ndarray介绍

ndarray

对象是Numpy科学工具包的核心,其本质是一个包含具有相同类型和内存大小的元素的多维容器。

多维数组的维度和各维度元素的数量由shape属性指定,数组的元素类型由dtype属性指定。

Numpy提供多种方法用于多维数组的创建、拼接、拆分等,具体可参考博文《Numpy数组的创建、变形、拼接及拆分》。

Numpy中的多维数组除具有python中其他容器的索引功能之外,还具有更强大的切片、整数数组、布尔数组等索引功能,具体实现可参考相关博文《Numpy数组的索引与切片:取数组的特定行列》。

不同

ndarrays

之间可以共享数据,即一个

ndarray

对象可能是另一个

ndarray

对象的视图,视图引用的数据由“base”ndarray处理。

ndarrays

还可以是python所拥有的内存视图或实现buffer或数组接口的对象。

ndarray的常用属性与方法

属性 功能
ndarray.ndim 数组的轴(维度)的个数
ndarray.shape 数组的形状,元组
ndarray.size 数组元素的总数,等于shape中各元素的乘积
ndarray.dtype 描述数组中元素类型的对象,可使用标准python数据类型创建
ndarray.itemsize 数组中每个元素的字节大小,如

float64

类型的数组,它等于64/8=8
ndarray.data 该缓冲区包含数组的实际元素,可使用索引替代,一般不直接使用
ndarray.strides 遍历数组时,每个维度上单步执行的步长
ndarray.base 若对象为视图则返回原始数组,若数据为其自身所有则返回None
ndarray.T 数组的转置
ndarray.flat 所有数据的一维迭代器

ndarray的转换方法

属性 功能
ndarray.item(*args) 返回数组指定位置的元素,位置可以是标量或元组
ndarray.tolist() 以列表(可能嵌套)的形式返回数组
ndarray.itemset(*args) 替换数组指定位置的元素,位置可以是标量或元组
ndarray.tostring(order=‘C’) 返回数组原始数据的字节序列
ndarray.tofile(fid, sep="", format="%s") 将数组作为文本或二进制(默认)写入文件
ndarray.dump(file) 将数组pickle到指定文件,对应load指令读取到内存
ndarray.dumps() 以字符串形式返回数组的pickle,对应loads指定从字符串读取为ndarry对象
ndarray.astype(dtype, order=‘K’, casting=‘unsafe’, subok=True, copy=True) 返回数组转换数据类型后副本
ndarray.byteswap(inplace=False) 交换数组元素的字节
ndarray.copy(order=‘C’) 返回数组的副本
ndarray.view(dtype=None, type=None) 返回数组的视图
ndarray.getfield(dtype, offset=0) 以某种类型返回数组的字段
ndarray.fill(value) 用标量值填充数组

3、数组运算

数组运算的注意事项:

  • 当使用不同类型的数组操作时,结果数组的类型对应于更一般或更精确的数组,即向上转换,因此不能对低精度的数组元素赋高精度的值;
  • 基本的算术、逻辑、位以及比较运算,需要创建新数组,并填充结果;
  • 复合运算符,如+=,为就地修改原数组,因此操作符右值不能是高精度的数据;
  • 普通乘法运算符

    *

    是元素级别运算,若需执行矩阵乘法运算,可使用

    @

    操作符或

    dot

    函数;
操作符/函数 功能
+ - * / ** >> << > < | & 算术、逻辑、位以及比较运算符使用元素级别,创建新数据并填充结果
+= -= *= /= >>= <<= 复合运算符,就地修改原数组数据
@ dot 矩阵乘法运算符
"""算术、逻辑、位以及比较运算符"""
>>> a = np.array( [20,30,40,50] )
>>> b = np.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*np.sin(a)
array([ 9.12945251, -9.88031624,  7.4511316 , -2.62374854])
>>> a < 35
array([ True, True, False, False])
>>> np.array([1,0,2]) & 1
array([1, 0, 0], dtype=int32)

"""复合运算符"""
>>> a = np.ones((2,3), dtype=int)
>>> b = np.random.random((2,3))
>>> a *= 3
>>> a
array([[3, 3, 3],
       [3, 3, 3]])
>>> b += a
>>> b
array([[ 3.417022  ,  3.72032449,  3.00011437],
       [ 3.30233257,  3.14675589,  3.09233859]])
>>> a += b                  # b is not automatically converted to integer type
Traceback (most recent call last):
  ...
TypeError: Cannot cast ufunc add output from dtype('float64') to dtype('int64') with casting rule 'same_kind'

"""普通乘法运算与矩阵乘法"""
>>> A = np.array([[1,1],[0,1]])
>>> B = np.array([[2,0],[3,4]])
>>> A * B
array([[2, 0],
       [0, 4]])
>>> A @ B
array([[5, 4],
       [3, 4]])
>>> np.dot(A,B)
array([[5, 4],
       [3, 4]])