NumPy

https://www.runoob.com/numpy/numpy-matplotlib.html
NumPy参考
Numpy and Scipy Documentation
NumPy Reference
NumPy quickstart
NumPy 中文

数据类型对象

数据类型对象(numpy.dtype 类的实例)用来描述与数组对应的内存区域是如何使用,它描述了数据的以下几个方面::

  • 数据的类型(整数,浮点数或者 Python 对象)
  • 数据的大小(例如, 整数使用多少个字节存储)
  • 数据的字节顺序(小端法或大端法)
  • 在结构化类型的情况下,字段的名称、每个字段的数据类型和每个字段所取的内存块的部分
  • 如果数据类型是子数组,那么它的形状和数据类型是什么。

字节顺序是通过对数据类型预先设定 < 或 > 来决定的。 < 意味着小端法(最小值存储在最小的地址,即低位组放在最前面)。> 意味着大端法(最重要的字节存储在最小的地址,即高位组放在最前面)。

dtype 对象是使用以下语法构造的:

numpy.dtype(object, align, copy)
  • object - 要转换为的数据类型对象
  • align - 如果为 true,填充字段使其类似 C 的结构体。
  • copy - 复制 dtype 对象 ,如果为 false,则是对内置数据类型对象的引用

数组标量类型

import numpy as np
dt = np.dtype(np.int32)
print(dt)

#int8,int16,int32,int64 可替换为等价的字符串 'i1','i2','i4',以及其他。
dt = np.dtype('i4')
print(dt)

a = np.array([10,20,30], dtype=dt)
print(a)
int32
int32
[10 20 30]

字节顺序

import numpy as np
# 字节顺序标注
dt = np.dtype('<i4')
print(dt)
int32

结构化数据类型

dt = np.dtype([('age',np.int8)])
print(dt)
# 将结构化数据应用于ndarray对象
a = np.array([(10,),(20,),(30,)],dtype = dt)
print(a)
# 访问age列内容
print(a['age'])
[('age', 'i1')]
[(10,) (20,) (30,)]
[10 20 30]

结构化数据包含多个字段

student = np.dtype([('name','S20'),('age','i1'),('marks','f4')])
a = np.array([('joe',20,80),('susan',22,85),('tom',23,90),('fank',23,33)],dtype=student)

print(student)
print(a)
print(a['name'])
print(a['age'])
print(a['marks'])
[('name', 'S20'), ('age', 'i1'), ('marks', '<f4')]
[(b'joe', 20, 80.) (b'susan', 22, 85.) (b'tom', 23, 90.) (b'fank', 23, 33.)]
[b'joe' b'susan' b'tom' b'fank']
[20 22 23 23]
[80. 85. 90. 33.]

内建类型字符代码

‘b’:布尔值
‘i’:符号整数
‘u’:无符号整数
‘f’:浮点
‘c’:复数浮点
‘m’:时间间隔
‘M’:日期时间
‘O’:Python 对象
‘S’, ‘a’:字节串
‘U’:Unicode
‘V’:原始数据(void)

Numpy数组属性

NumPy 数组的维数称为秩(rank),秩就是轴的数量,即数组的维度,一维数组的秩为 1,二维数组的秩为 2,以此类推。
axis=0,表示沿着第 0 轴进行操作,即对每一列进行操作;axis=1,表示沿着第1轴进行操作,即对每一行进行操作。
NumPy 的数组中比较重要 ndarray 对象属性有:

属性说明
ndarray.ndim秩,即轴的数量或维度的数量
ndarray.shape数组的维度,对于矩阵,n 行 m 列
ndarray.size数组元素的总个数,相当于 .shape 中 n*m 的值
ndarray.dtypendarray 对象的元素类型
ndarray.itemsizendarray 对象中每个元素的大小,以字节为单位
ndarray.flagsndarray 对象的内存信息
ndarray.realndarray元素的实部
ndarray.imagndarray 元素的虚部
ndarray.data包含实际数组元素的缓冲区,由于一般通过数组的索引获取元素,所以通常不需要使用这个属性。

ndarray.ndim

ndarray.ndim 用于返回数组的维数,等于秩。

实例

import numpy as np 
 
a = np.arange(24)  
print(a)
print (a.ndim)             # a 现只有一个维度
# 现在调整其大小
b = a.reshape(2,4,3)  # b 现在拥有三个维度
print(b)
print(b.ndim)

输出结果为:

[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
1
[[[ 0  1  2]
  [ 3  4  5]
  [ 6  7  8]
  [ 9 10 11]]

 [[12 13 14]
  [15 16 17]
  [18 19 20]
  [21 22 23]]]
3

ndarray.reshape()

ndarray.reshape 通常返回的是非拷贝副本,即改变返回后数组的元素,原数组对应元素的值也会改变。

import numpy as np

a=np.array([[1,2,3],[4,5,6]])
b=a.reshape((6,))

a
array([[1, 2, 3],
       [4, 5, 6]])
b
array([1, 2, 3, 4, 5, 6])

# 更改b中元素内容,a中也改变
b[0]=100

b
array([100,   2,   3,   4,   5,   6])
a
array([[100,   2,   3],
       [  4,   5,   6]])

ndarray.shape

ndarray.shape 表示数组的维度,返回一个元组,这个元组的长度就是维度的数目,即 ndim 属性(秩)。比如,一个二维数组,其维度表示"行数"和"列数"。

ndarray.shape 也可以用于调整数组大小。

import numpy as np  
 
a = np.array([[1,2,3],[4,5,6]])  
print (a.shape)

输出结果为:

(2, 3)

调整数组大小。

实例

import numpy as np 
 
a = np.array([[1,2,3],[4,5,6]]) 
a.shape =  (3,2)  
print (a)

输出结果为:

[[1 2]
 [3 4]
 [5 6]]

NumPy 也提供了 reshape 函数来调整数组大小。

实例

import numpy as np 
 
a = np.array([[1,2,3],[4,5,6]]) 
b = a.reshape(3,2)  
print (b)

输出结果为:

[[1, 2] 
 [3, 4] 
 [5, 6]]

ndarray.itemsize

ndarray.itemsize 以字节的形式返回数组中每一个元素的大小。

例如,一个元素类型为 float64 的数组 itemsize 属性值为 8(float64 占用 64 个 bits,每个字节长度为 8,所以 64/8,占用 8 个字节),又如,一个元素类型为 complex32 的数组 item 属性为 4(32/8)。

import numpy as np 
 
# 数组的 dtype 为 int8(一个字节)  
x = np.array([1,2,3,4,5], dtype = np.int8)  
print (x.itemsize)
 
# 数组的 dtype 现在为 float64(八个字节) 
y = np.array([1,2,3,4,5], dtype = np.float64)  
print (y.itemsize)

输出结果为:

1
8

ndarray.flags

ndarray.flags 返回 ndarray 对象的内存信息,包含以下属性:

属性描述
C_CONTIGUOUS ©数据是在一个单一的C风格的连续段中
F_CONTIGUOUS (F)数据是在一个单一的Fortran风格的连续段中
OWNDATA (O)数组拥有它所使用的内存或从另一个对象中借用它
WRITEABLE (W)数据区域可以被写入,将该值设置为 False,则数据为只读
ALIGNED (A)数据和所有元素都适当地对齐到硬件上
UPDATEIFCOPY (U)这个数组是其它数组的一个副本,当这个数组被释放时,原数组的内容将被更新

实例

import numpy as np 
 
x = np.array([1,2,3,4,5])  
print (x.flags)

输出结果为:

  C_CONTIGUOUS : True
  F_CONTIGUOUS : True
  OWNDATA : True
  WRITEABLE : True
  ALIGNED : True
  WRITEBACKIFCOPY : False
  UPDATEIFCOPY : False

NumPy 创建数组

numpy.empty()

numpy.empty 方法用来创建一个指定形状(shape)、数据类型(dtype)且未初始化的数组:

numpy.empty(shape, dtype = float, order = ‘C’)

参数说明:

  • shape 数组形状
  • dtype 数据类型,可选
  • order 有"C"和"F"两个选项,分别代表,行优先和列优先,在计算机内存中的存储元素的顺序。
import numpy as np 
x = np.empty([3,2], dtype = int) 
print (x)

结果:

[[1 2]
 [3 4]
 [5 6]]

numpy.zero()

创建指定大小的数组,数组元素以 0 来填充:

numpy.zeros(shape, dtype = float, order = ‘C’)

参数说明:

  • shape 数组形状
  • dtype 数据类型,可选
  • order ‘C’ 用于 C 的行数组,或者 ‘F’ 用于 FORTRAN 的列数组
import numpy as np
 
# 默认为浮点数
x = np.zeros(5) 
print(x)
 
# 设置类型为整数
y = np.zeros((5,), dtype = np.int) 
print(y)
 
# 自定义类型
z = np.zeros((2,2), dtype = [('x', 'i4'), ('y', 'i4')])  
print(z)

结果:

[0. 0. 0. 0. 0.]
[0 0 0 0 0]
[[(0, 0) (0, 0)]
 [(0, 0) (0, 0)]]

numpy.ones()

创建指定形状的数组,数组元素以 1 来填充:

numpy.ones(shape, dtype = None, order = ‘C’)

参数说明:

  • shape 数组形状
  • dtype 数据类型,可选
  • order ‘C’ 用于 C 的行数组,或者 ‘F’ 用于 FORTRAN 的列数组
import numpy as np
 
# 默认为浮点数
x = np.ones(5) 
print(x)
 
# 自定义类型
x = np.ones([2,2], dtype = int)
print(x)
[1. 1. 1. 1. 1.]
[[1 1]
 [1 1]]

numpy.random.randn()

Numpy 创建标准正态分布数组

numpy.random.randn(d0, d1…)

from numpy import *

# 创建 randn(size) 服从 X~N(0,1) 的正态分布随机数组
a=random.randn(2,3)
print(a)
[[ 0.40407526  0.5444481   0.54987026]
 [-0.70860137 -1.08504124 -0.74730332]]

numpy.random.randint()

numpy.random.randint用法
Numpy 创建随机分布整数型数组。

利用 randint([low,high],size) 创建一个整数型指定范围在 [low.high) 之间的数组。如果没写high值,返回[0,low)的值。

numpy.random.randint(low, high=None, size=None, dtype=int)

参数:

  • low: int
    生成的数值最低要大于等于low。
    (hign = None时,生成的数值要在[0, low)区间内)
  • high: int (可选)
    如果使用这个值,则生成的数值在[low, high)区间。
  • size: int or tuple of ints(可选)
    输出随机数的尺寸,比如size = (m * n* k)则输出同规模即m * n* k个随机数。默认是None的,仅仅返回满足要求的单一随机数。
  • dtype: dtype(可选):
    想要输出的格式。如int64、int等等
>>> np.random.randint(2, size=10)
array([1, 0, 0, 0, 1, 1, 0, 0, 1, 0])
>>> np.random.randint(1, size=10)
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

>>> np.random.randint(5, size=(2, 4))
array([[4, 0, 2, 1],
       [3, 2, 2, 0]])

>>>np.random.randint(2, high=10, size=(2,3))
array([[6, 8, 7],
       [2, 5, 2]])

numpy.arange()

Numpy 中 arange() 主要是用于生成数组,在给定区间[start, stop)内返回均匀间隔的值。

numpy.arange([start,] stop[, step,], dtype=None)

  • start —— 开始位置,数字,可选项,默认起始值为0
  • stop —— 停止位置,数字
  • step —— 步长,数字,可选项, 默认步长为1,如果指定了step,则还必须给出start。
  • dtype —— 输出数组的类型。 如果未给出dtype,则从其他输入参数推断数据类型。
 >>> np.arange(3)
    array([0, 1, 2])
    >>> np.arange(3.0)
    array([ 0.,  1.,  2.])
    >>> np.arange(3,7)
    array([3, 4, 5, 6])
    >>> np.arange(3,7,2)
    array([3, 5])

numpy.eye()

eye 创建对角矩阵数组,即返回一个二维数组,其中对角线为1,其余为零。

numpy.eye(N, M=None, k=0, dtype=<class ‘float’>, order=‘C’)

参数:

  • N : int
    输出中的行数。
  • M : int,可选
    输出中的列数。如果无,默认为Ñ。
  • k : int,可选
    对角线的索引:0(默认值)指的是主对角线,正值指的是上对角线,负值指的是下对角线。
  • dtype : 数据类型,可选
    返回数组的数据类型。
  • order: {‘C’,‘F’},可选
    输出是否应以内存中的行主(C风格)或列主(Fortran风格)顺序存储。
import numpy as np
print(np.eye(2, dtype=int))
输出结果:[[1 0]
          [0 1]]
print(np.eye(3, k=1))   
输出结果:[[0. 1. 0.]
          [0. 0. 1.]
          [0. 0. 0.]]
np.eye(2,3)
array([[1., 0., 0.],
       [0., 1., 0.]])
np.eye(3,2)
array([[1., 0.],
       [0., 1.],
       [0., 0.]])

numpy.array()

python中数组(numpy.array)的基本操作

numpy.array(object, dtype=None, *, copy=True, order=‘K’, subok=False, ndmin=0)

参数说明:

  • object:数组
    公开数组接口的任何对象,__array__方法返回数组的对象,或任何(嵌套)序列。

  • dtype : 数据类型,可选
    数组所需的数据类型。如果没有给出,那么类型将被确定为保持序列中的对象所需的最小类型。此参数只能用于“upcast”数组。对于向下转换,请使用.astype(t)方法。

  • copy : bool,可选
    如果为true(默认值),则复制对象。否则,只有当__array__返回副本,obj是嵌套序列,或者需要副本来满足任何其他要求(dtype,顺序等)时,才会进行复制。

  • order : {‘K’,‘A’,‘C’,‘F’},可选
    指定阵列的内存布局。如果object不是数组,则新创建的数组将按C顺序排列(行主要),除非指定了’F’,在这种情况下,它将采用Fortran顺序(专业列)。如果object是一个数组,则以下成立。
    当copy=False出于其他原因而复制时,结果copy=True与对A的一些例外情况相同,请参阅“注释”部分。默认顺序为“K”。

  • subok : bool,可选
    如果为True,则子类将被传递,否则返回的数组将被强制为基类数组(默认)。

  • ndmin : int,可选
    指定结果数组应具有的最小维数。根据需要,将根据需要预先设置形状。

>>> np.array([1, 2, 3]) 
array([1, 2, 3])


二维
>>> np.array([[1, 2], [3, 4]]) 
array([[1, 2], [3, 4]])

最小维度为2>>> np.array([1, 2, 3], ndmin=2) 
array([[1, 2, 3]])

提供类型
>>> np.array([1, 2, 3], dtype=complex) 
array([ 1.+0.j, 2.+0.j, 3.+0.j])

由多个元素组成的数据类型:
>>> x = np.array([(1,2),(3,4)],dtype=[('a','<i4'),('b','<i4')]) 
>>> x['a'] 
array([1, 3])

从子类创建数组:
>>> np.array(np.mat('1 2; 3 4')) 
array([[1, 2], [3, 4]]) 
>>> np.array(np.mat('1 2; 3 4'), subok=True) 
matrix([[1, 2], [3, 4]])

数组的常用函数

print np.arange(0,7,1,dtype=np.int16) # 0为起点,间隔为1时可缺省(引起歧义下不可缺省)
print np.ones((2,3,4),dtype=np.int16) # 2页,3行,4列,全1,指定数据类型
print np.zeros((2,3,4)) # 2页,3行,4列,全0
print np.empty((2,3)) #值取决于内存
print np.arange(0,10,2) # 起点为0,不超过10,步长为2
print np.linspace(-1,2,5) # 起点为-1,终点为2,取5个点
print np.random.randint(0,3,(2,3)) # 大于等于0,小于3,2行3列的随机整数

order参数的’A’,‘C’,‘F’

以reshape中的order参数为例:

You can think of reshaping as first raveling the array (using the givenindex order), then inserting the elements from the raveled array into thenew array using the same kind of index ordering as was used for theraveling.

翻译过来就是先打散,再按照这个顺序插入

C 是按照行顺序, F 是按照列顺序,A 就是按照数据在内存中存储的顺序来。
比如:

a = array([[0, 1],
           [2, 3],
           [4, 5]])

np.reshape(a, (2, 3), order='F')

Out[9]: 
array([[0, 4, 3],
       [2, 1, 5]])

按照 F 顺序打散后就是 0 2 4 1 3 5, 再按照 F顺序插入, 就是结果。

但是有个地方在多维数据的时候容易混淆,就是当我们按照 C 是按照行顺序, F 是按照列顺序去理解的时候多维度数据的时候,这样的解释就不够了,更一般的理解,应该是 C 顺序准确的含义是从最里面的轴开始读写,而F顺序则是从最外面的轴开始读写

什么意思呢? 以上面的二维数据 a(3,2) 举例就是,C顺序就是先读写最里面 2 这个轴的数据,也就是得到 0 ,1 ,2,3,4,5 这样的顺序,而F顺序则是从最外层 3 这个轴的数据开始读写,得到 0 2 4 1 3 5,多维数据以此类推。
比如三维数据:

>>> a
array([[[ 0,  1],
        [ 2,  3],
        [ 4,  5]],

       [[ 6,  7],
        [ 8,  9],
        [10, 11]]])
>>> reshape(a,(4,3))
array([[ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 9, 10, 11]])
>>> reshape(a,(4,3),order='F')
array([[ 0,  4,  3],
       [ 6, 10,  9],
       [ 2,  1,  5],
       [ 8,  7, 11]])

a按F顺序读取,先2轴,再1轴,最后0轴方式读数据,即坐标(0,0,0)和(1,0,0),即0,6。然后(0,1,0)和(1,1,0)数据2,8.。一直读到最后。
全部读出来的顺序是0,6,2,8,4,10,1,7,3,9,5,11.
然后按F顺序插入,即最后的结果。

NumPy 从已有的数组创建数组

numpy.asarray

numpy.asarray 类似 numpy.array,但 numpy.asarray 参数只有三个,比 numpy.array 少两个。

numpy.asarray(a, dtype = None, order = None)

参数说明:

  • a 任意形式的输入参数,可以是,列表, 列表的元组, 元组, 元组的元组, 元组的列表,多维数组
  • dtype 数据类型,可选
  • order 可选,有"C"和"F"两个选项,分别代表,行优先和列优先,在计算机内存中的存储元素的顺序。

将列表转换为 ndarray:

import numpy as np 
 
x =  [1,2,3] 
a = np.asarray(x)  
print (a)
输出结果为:

[1  2  3]

将元组转换为 ndarray:

import numpy as np 
 
x =  (1,2,3) 
a = np.asarray(x)  
print (a)
输出结果为:

[1  2  3]

将元组列表转换为 ndarray:

import numpy as np 
 
x =  [(1,2,3),(4,5)] 
a = np.asarray(x)  
print (a)
输出结果为:

[(1, 2, 3) (4, 5)]

numpy.frombuffer

numpy.frombuffer 用于实现动态数组。

numpy.frombuffer 接受 buffer 输入参数,以流的形式读入转化成 ndarray 对象。

numpy.frombuffer(buffer, dtype = float, count = -1, offset = 0)

注意:buffer 是字符串的时候,Python3 默认 str 是 Unicode 类型,所以要转成 bytestring 在原 str 前加上 b。

参数说明:

  • buffer 可以是任意对象,会以流的形式读入。
  • dtype 返回数组的数据类型,可选
  • count 读取的数据数量,默认为-1,读取所有数据。
  • offset 读取的起始位置,默认为0。
import numpy as np 
 
s =  b'Hello World!' 
a = np.frombuffer(s, dtype =  'S1')  
b = np.frombuffer(s, dtype =  'S2')
print (a)
print (b)
输出结果为:
[b'H', b'e', b'l', b'l', b'o', b' ', b'W', b'o', b'r', b'l', b'd', b'!']
[b'He' b'll' b'o ' b'Wo' b'rl' b'd!']

Python2.x 实例
import numpy as np
s =  'Hello World'
a = np.frombuffer(s, dtype =  'S1')
print (a)
输出结果为:
['H' 'e' 'l' 'l' 'o' ' ' 'W' 'o' 'r' 'l' 'd']

numpy.fromiter

numpy.fromiter 方法从可迭代对象中建立 ndarray 对象,返回一维数组。

numpy.fromiter(iterable, dtype, count=-1)

参数 描述

  • iterable 可迭代对象
  • dtype 返回数组的数据类型
  • count 读取的数据数量,默认为-1,读取所有数据
import numpy as np 
 
# 使用 range 函数创建列表对象  
list=range(5)
it=iter(list)
 
# 使用迭代器创建 ndarray 
x=np.fromiter(it, dtype=float)
print(x)
输出结果为:
[0. 1. 2. 3. 4.]

NumPy 从数值范围创建数组

numpy.arange

numpy 包中的使用 arange 函数创建数值范围并返回 ndarray 对象,函数格式如下:

numpy.arange(start, stop, step, dtype)

根据 start 与 stop 指定的范围以及 step 设定的步长,生成一个 ndarray。

参数说明:

  • start 起始值,默认为0
  • stop 终止值(不包含)
  • step 步长,默认为1
  • dtype 返回ndarray的数据类型,如果没有提供,则会使用输入数据的类型。

生成 0 到 5 的数组:

import numpy as np
 
x = np.arange(5)  
print (x)
输出结果如下:
[0  1  2  3  4]

设置返回类型位 float:

import numpy as np
 
# 设置了 dtype
x = np.arange(5, dtype =  float)  
print (x)
输出结果如下:
[0.  1.  2.  3.  4.]

设置了起始值、终止值及步长:

import numpy as np
x = np.arange(10,20,2)  
print (x)
输出结果如下:
[10  12  14  16  18]

numpy.linspace

numpy.linspace 函数用于创建一个一维数组,数组是一个等差数列构成的,格式如下:

np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)

参数说明:

  • start 序列的起始值
  • stop 序列的终止值,如果endpoint为true,该值包含于数列中
  • num 要生成的等步长的样本数量,默认为50
  • endpoint 该值为 true 时,数列中包含stop值,反之不包含,默认是True。
  • retstep 如果为 True 时,生成的数组中会显示间距,反之不显示。
  • dtype ndarray 的数据类型

设置起始点为 1 ,终止点为 10,数列个数为 10。

import numpy as np
a = np.linspace(1,10,10)
print(a)
输出结果为:
[ 1.  2.  3.  4.  5.  6.  7.  8.  9. 10.]

设置元素全部是1的等差数列:

import numpy as np
a = np.linspace(1,1,10)
print(a)
输出结果为:
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]

将 endpoint 设为 false,不包含终止值:

import numpy as np
 
a = np.linspace(10, 20,  5, endpoint =  False)  
print(a)
输出结果为:
[10. 12. 14. 16. 18.]

如果将 endpoint 设为 true,则会包含 20。

设置间距。

import numpy as np
a =np.linspace(1,10,10,retstep= True)
 
print(a)
# 拓展例子
b =np.linspace(1,10,10).reshape([10,1])
print(b)

输出结果为:
(array([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10.]), 1.0)
[[ 1.]
 [ 2.]
 [ 3.]
 [ 4.]
 [ 5.]
 [ 6.]
 [ 7.]
 [ 8.]
 [ 9.]
 [10.]]

numpy.logspace

numpy.logspace 函数用于创建一个于等比数列。格式如下:

np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)

base 参数意思是取对数的时候 log 的下标。

参数

  • start 序列的起始值为:base ** start
  • stop 序列的终止值为:base ** stop。如果endpoint为true,该值包含于数列中
  • num 要生成的等步长的样本数量,默认为50
  • endpoint 该值为 true 时,数列中中包含stop值,反之不包含,默认是True。
  • base 对数 log 的底数。
  • dtype ndarray 的数据类型

默认底数是10

import numpy as np
# 默认底数是 10
a = np.logspace(1.0,  2.0, num =  10)  
print (a)
输出结果为:
[ 10.           12.91549665     16.68100537      21.5443469  27.82559402      
  35.93813664   46.41588834     59.94842503      77.42636827    100.    ]

将对数的底数设置为 2 :

import numpy as np
a = np.logspace(0,9,10,base=2)
print (a)
输出如下:
[  1.   2.   4.   8.  16.  32.  64. 128. 256. 512.]

NumPy 切片和索引

ndarray对象的内容可以通过索引或切片来访问和修改,与 Python 中 list 的切片操作一样。

ndarray 数组可以基于 0 - n 的下标进行索引,切片对象可以通过内置的 slice 函数,并设置 start, stop 及 step 参数进行,从原数组中切割出一个新数组。

import numpy as np
 
a = np.arange(10)
s = slice(2,7,2)   # 从索引 2 开始到索引 7 停止,间隔为2
print (a[s])
print (a[2:7:2])
输出结果为:
[2  4  6]
[2  4  6]

冒号 : 的解释:如果只放置一个参数,如 [2],将返回与该索引相对应的单个元素。如果为 [2:],表示从该索引开始以后的所有项都将被提取。如果使用了两个参数,如 [2:7],那么则提取两个索引(不包括停止索引)之间的项。

import numpy as np
 
a = np.arange(10)  # [0 1 2 3 4 5 6 7 8 9]
b = a[5] 
print(b)
输出结果为:
5

print(a[2:])
输出结果为:
[2  3  4  5  6  7  8  9]

print(a[2:5])
输出结果为:
[2  3  4]

多维数组同样适用上述索引提取方法:

import numpy as np
 
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
print(a)
# 从某个索引处开始切割
print('从数组索引 a[1:] 处开始切割')
print(a[1:])

[[1 2 3]
 [3 4 5]
 [4 5 6]]
从数组索引 a[1:] 处开始切割
[[3 4 5]
 [4 5 6]]

这样只能对最外层轴切片
a[1:][1:]
array([[4, 5, 6]])

a[1][1]
4

任意轴切片

import numpy as np
 
a = np.array([[1,2,3],[3,4,5],[4,5,6]])  

第二行元素
a[1,...]
array([3, 4, 5])

行切片
a[1:,...]
array([[3, 4, 5],
       [4, 5, 6]])

第二列元素
a[...,1]
array([2, 4, 5])

列切片
 a[...,1:]
array([[2, 3],
       [4, 5],
       [5, 6]])

两个轴上同时切片
a[1:,1:]
array([[4, 5],
       [5, 6]])

NumPy 高级索引

NumPy 比一般的 Python 序列提供更多的索引方式。除了之前看到的用整数和切片的索引外,数组可以由整数数组索引、布尔索引及花式索引。

整数数组索引

以下实例获取数组中(0,0),(1,1)和(2,0)位置处的元素。

import numpy as np 
 
x = np.array([[1,  2],  [3,  4],  [5,  6]]) 
y = x[[0,1,2],  [0,1,0]]  
print (y)
输出结果为:
[1  4  5]

以下实例获取了 4X3 数组中的四个角的元素。 行索引是 [0,0] 和 [3,3],而列索引是 [0,2] 和 [0,2]。

x = np.array([[  0,  1,  2],[  3,  4,  5],[  6,  7,  8],[  9,  10,  11]])
x
array([[ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 9, 10, 11]])

x[[0,0,3,3],[0,2,0,2]]
array([ 0,  2,  9, 11])

x[[[0,0],[3,3]],[[0,2],[0,2]]]
array([[ 0,  2],
       [ 9, 11]])

rows = np.array([[0,0],[3,3]]) 
cols = np.array([[0,2],[0,2]])
x[rows,cols]
array([[ 0,  2],
       [ 9, 11]])

可以借助切片 : 或 … 与索引数组组合

import numpy as np
 
a = np.array([[1,2,3], [4,5,6],[7,8,9]])
a
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

a[1:3,1:3]
array([[5, 6],
       [8, 9]])

a[1:3,[1,2]]
array([[5, 6],
       [8, 9]])

a[...,1:]
array([[2, 3],
       [5, 6],
       [8, 9]])

布尔索引

我们可以通过一个布尔数组来索引目标数组。

布尔索引通过布尔运算(如:比较运算符)来获取符合指定条件的元素的数组。
获取大于 5 的元素:

import numpy as np 
 
x = np.array([[  0,  1,  2],[  3,  4,  5],[  6,  7,  8],[  9,  10,  11]])
x
array([[ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 9, 10, 11]])
大于 5 的元素是
x[x>5]
array([ 6,  7,  8,  9, 10, 11])

使用了 ~(取补运算符)来过滤 NaN。

import numpy as np 
 
a = np.array([np.nan,  1,2,np.nan,3,4,5])  
a
array([nan,  1.,  2., nan,  3.,  4.,  5.])

a[~np.isnan(a)]
array([1., 2., 3., 4., 5.])

从数组中过滤掉非复数元素

import numpy as np 
 
a = np.array([1,  2+6j,  5,  3.5+5j])  

print (a[np.iscomplex(a)])
[2.0+6.j  3.5+5.j]

花式索引

花式索引指的是利用整数数组进行索引。

花式索引根据索引数组的值作为目标数组的某个轴的下标来取值。对于使用一维整型数组作为索引,如果目标是一维数组,那么索引的结果就是对应位置的元素;如果目标是二维数组,那么就是对应下标的行。

花式索引跟切片不一样,它总是将数据复制到新数组中
1、传入顺序索引数组

import numpy as np 
 
x=np.arange(32).reshape((8,4))
x
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15],
       [16, 17, 18, 19],
       [20, 21, 22, 23],
       [24, 25, 26, 27],
       [28, 29, 30, 31]])

索引为4,2,1,7的行构成新数组
x[[4,2,1,7]]
array([[16, 17, 18, 19],
       [ 8,  9, 10, 11],
       [ 4,  5,  6,  7],
       [28, 29, 30, 31]])

x[[4,2,1,7],1:3]
array([[17, 18],
       [ 9, 10],
       [ 5,  6],
       [29, 30]])

2、传入倒序索引数组

import numpy as np 
 
x=np.arange(32).reshape((8,4))
x
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15],
       [16, 17, 18, 19],
       [20, 21, 22, 23],
       [24, 25, 26, 27],
       [28, 29, 30, 31]])
       
print (x[[-4,-2,-1,-7]])
输出结果为:
[[16 17 18 19]
 [24 25 26 27]
 [28 29 30 31]
 [ 4  5  6  7]]

3、传入多个索引数组(要使用np.ix_)

import numpy as np 
 
x=np.arange(32).reshape((8,4))
x
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15],
       [16, 17, 18, 19],
       [20, 21, 22, 23],
       [24, 25, 26, 27],
       [28, 29, 30, 31]])
print (x[np.ix_([1,5,7,2],[0,3,1,2])])
输出结果为:
[[ 4  7  5  6]
 [20 23 21 22]
 [28 31 29 30]
 [ 8 11  9 10]]

y = np.arange(27).reshape(3,3,3)
y
array([[[ 0,  1,  2],
        [ 3,  4,  5],
        [ 6,  7,  8]],

       [[ 9, 10, 11],
        [12, 13, 14],
        [15, 16, 17]],

       [[18, 19, 20],
        [21, 22, 23],
        [24, 25, 26]]])
y[np.ix_([1,2],[1,2],[1,2])]
array([[[13, 14],
        [16, 17]],

       [[22, 23],
        [25, 26]]])

NumPy 广播(Broadcast)

广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式, 对数组的算术运算通常在相应的元素上进行。

如果两个数组 a 和 b 形状相同,即满足 a.shape == b.shape,那么 a*b 的结果就是 a 与 b 数组对应位相乘。这要求维数相同,且各维度的长度相同。
相同形状数组相乘

import numpy as np 
 
a = np.array([1,2,3,4]) 
b = np.array([10,20,30,40]) 
c = a * b 
print (c)
输出结果为:
[ 10  40  90 160]

不同形状数组计算
当运算中的 2 个数组的形状不同时,numpy 将自动触发广播机制。如:

import numpy as np 
 
a = np.array([[ 0, 0, 0],
           [10,10,10],
           [20,20,20],
           [30,30,30]])
b = np.array([1,2,3])
print(a + b)
输出结果为:

[[ 1  2  3]
 [11 12 13]
 [21 22 23]
 [31 32 33]]

4x3 的二维数组与长为 3 的一维数组相加,等效于把数组 b 在二维上重复 4 次再运算:

import numpy as np 
 
a = np.array([[ 0, 0, 0],
           [10,10,10],
           [20,20,20],
           [30,30,30]])
b = np.array([1,2,3])
bb = np.tile(b, (4, 1))  # 重复 b 的各个维度
print(a + bb)
输出结果为:

[[ 1  2  3]
 [11 12 13]
 [21 22 23]
 [31 32 33]]

广播的规则:

  • 让所有输入数组都向其中形状最长的数组看齐,形状中不足的部分都通过在前面加 1 补齐。
  • 输出数组的形状是输入数组形状的各个维度上的最大值。
  • 如果输入数组的某个维度和输出数组的对应维度的长度相同或者其长度为 1 时,这个数组能够用来计算,否则出错。
  • 当输入数组的某个维度的长度为 1 时,沿着此维度运算时都用此维度上的第一组值。

简单理解:对两个数组,分别比较他们的每一个维度(若其中一个数组没有当前维度则忽略),满足:

  • 数组拥有相同形状。
  • 当前维度的值相等。
  • 当前维度的值有一个是 1。

若条件不满足,抛出 “ValueError: frames are not aligned” 异常。

numpy.tile()

原型:numpy.tile(A,reps)

tile共有2个参数,A指待输入数组,reps则决定A重复的次数。整个函数用于重复数组A来构建新的数组。
假设reps的维度为d,那么新数组的维度为max(d,A.ndim)。下面分三种情况进行讨论:

  • (1)A.dim < d
    则向A中添加新轴扩充A的维度。维度大小可以从shape中看出,一般通过向shape对应的元组中添加1完成对A维度的扩充。扩充完成后,则可根据reps的值对A中相应维度的值进行重复。
    例如,一维数组shape为(3,),扩充至2维则shape值为(1,3),扩充至3维则shape值为(1,1,3)
  • (2)A.dim > d
    将reps扩充至与A相同的维度。扩充方法同上,也是向shape对应元组中添1,然后再进行重复。
    例如,4维数组A的shape为(2,3,4,5),而reps为(2,2)只有2维,那么就要对reps添维进行扩充,得到(1,1,2,2)
  • (3)A.dim = d
    不需要扩充,直接按reps的值对相应维度的值进行重复。
a = np.array([0, 1, 2])
np.tile(a, 2)
array([0, 1, 2, 0, 1, 2])

np.tile(a, (2, 2))
array([[0, 1, 2, 0, 1, 2],
       [0, 1, 2, 0, 1, 2]])
b = np.array([[1, 2], [3, 4]])
np.tile(b, 2)
array([[1, 2, 1, 2],
       [3, 4, 3, 4]])
np.tile(b, (2, 1))
array([[1, 2],
       [3, 4],
       [1, 2],
       [3, 4]])
c = np.array([1,2,3,4])
np.tile(c,(4,1))
array([[1, 2, 3, 4],
       [1, 2, 3, 4],
       [1, 2, 3, 4],
       [1, 2, 3, 4]])

NumPy 迭代数组

NumPy 迭代器对象 numpy.nditer 提供了一种灵活访问一个或者多个数组元素的方式。

迭代器最基本的任务的可以完成对数组元素的访问。

使用 nditer 对数组进行迭代

a = np.arange(6).reshape(2,3)
print(a)
for x in np.nditer(a):
    print (x, end=", " )
[[0 1 2]
 [3 4 5]]
0,1,2,3,4,5,

以上实例不是使用标准 C 或者 Fortran 顺序,选择的顺序是和数组内存布局一致的,这样做是为了提升访问的效率,默认是行序优先(row-major order,或者说是 C-order)。

这反映了默认情况下只需访问每个元素,而无需考虑其特定顺序。我们可以通过迭代上述数组的转置来看到这一点,并与以 C 顺序访问数组转置的 copy 方式做对比,如下实例:

import numpy as np
 
a = np.arange(6).reshape(2,3)
print(a.T)
for x in np.nditer(a.T):
    print (x, end=", " )
print(a.T.copy())
for x in np.nditer(a.T.copy(order='C')):
    print (x, end=", " )
[[0 3]
 [1 4]
 [2 5]]
0, 1, 2, 3, 4, 5,
[[0 3]
 [1 4]
 [2 5]]
0, 3, 1, 4, 2, 5,

从上述例子可以看出,a 和 a.T 的遍历顺序是一样的,也就是他们在内存中的存储顺序也是一样的,但是 a.T.copy(order = ‘C’) 的遍历结果是不同的,那是因为它和前两种的存储方式是不一样的,默认是按行访问。
a.T并没有按C序排列元素。copy操作后,才会按照指定的顺序排列元素,默认按照C序.

控制遍历顺序

  • for x in np.nditer(a, order=‘F’):Fortran order,即是列序优先;
  • for x in np.nditer(a.T, order=‘C’):C order,即是行序优先;
a = np.arange(0,60,5).reshape(3,4)
a
array([[ 0,  5, 10, 15],
       [20, 25, 30, 35],
       [40, 45, 50, 55]])

b = a.T
b
array([[ 0, 20, 40],
       [ 5, 25, 45],
       [10, 30, 50],
       [15, 35, 55]])

以 C 风格顺序排序:
c = b.copy(order='C')
c
array([[ 0, 20, 40],
       [ 5, 25, 45],
       [10, 30, 50],
       [15, 35, 55]])
for x in np.nditer(c):  
    print (x, end=", " )    
0, 20, 40, 5, 25, 45, 10, 30, 50, 15, 35, 55,

以 F 风格顺序排序:
c = b.copy(order='F')
c
array([[ 0, 20, 40],
       [ 5, 25, 45],
       [10, 30, 50],
       [15, 35, 55]])
for x in np.nditer(c):  
    print (x, end=", " )
0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 

通过显式设置,来强制 nditer 对象使用某种顺序

a = np.arange(0,60,5).reshape(3,4)
a
array([[ 0,  5, 10, 15],
       [20, 25, 30, 35],
       [40, 45, 50, 55]])

以 C 风格顺序排序:
for x in np.nditer(a, order =  'C'):  
    print (x, end=", " )
0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 

以 F 风格顺序排序:
for x in np.nditer(a, order =  'F'):  
    print (x, end=", " )
0, 20, 40, 5, 25, 45, 10, 30, 50, 15, 35, 55, 

修改数组中元素的值

nditer 对象有另一个可选参数 op_flags。 默认情况下,nditer 将视待迭代遍历的数组为只读对象(read-only),为了在遍历数组的同时,实现对数组元素值得修改,必须指定 read-write 或者 write-only 的模式。

a = np.arange(0,60,5).reshape(3,4)
a
array([[ 0,  5, 10, 15],
       [20, 25, 30, 35],
       [40, 45, 50, 55]])
       
for x in np.nditer(a, op_flags=['readwrite']): 
    x[...]=2*x 
a
array([[  0,  10,  20,  30],
       [ 40,  50,  60,  70],
       [ 80,  90, 100, 110]])

使用外部循环

nditer类的构造器拥有flags参数,它可以接受下列值:

  • c_index 可以跟踪 C 顺序的索引
  • f_index 可以跟踪 Fortran 顺序的索引
  • multi-index 每次迭代可以跟踪一种索引类型
  • external_loop 给出的值是具有多个值的一维数组,而不是零维数组
a = np.arange(0,60,5).reshape(3,4)
a
array([[ 0,  5, 10, 15],
       [20, 25, 30, 35],
       [40, 45, 50, 55]])

for x in np.nditer(a, flags =  ['external_loop'], order =  'F'):  
   print (x, end=", " )
[ 0 20 40], [ 5 25 45], [10 30 50], [15 35 55],

广播迭代

如果两个数组是可广播的,nditer 组合对象能够同时迭代它们。 假设数组 a 的维度为 3X4,数组 b 的维度为 1X4 ,则使用以下迭代器(数组 b 被广播到 a 的大小)。

a = np.arange(0,60,5).reshape(3,4)
a
array([[ 0,  5, 10, 15],
       [20, 25, 30, 35],
       [40, 45, 50, 55]])

b = np.array([1,  2,  3,  4], dtype =  int)
b
array([1, 2, 3, 4])

for x,y in np.nditer([a,b]):  
    print ("%d:%d"  %  (x,y), end=", " )
0:1, 5:2, 10:3, 15:4, 20:1, 25:2, 30:3, 35:4, 40:1, 45:2, 50:3, 55:4,

Numpy 数组操作

Numpy 中包含了一些函数用于处理数组,大概可分为以下几类:

  • 修改数组形状
  • 翻转数组
  • 修改数组维度
  • 连接数组
  • 分割数组
  • 数组元素的添加与删除

修改数组形状

  • reshape 不改变数据的条件下修改形状
  • flat 数组元素迭代器
  • flatten 返回一份数组拷贝,对拷贝所做的修改不会影响原始数组
  • ravel 返回展开数组

numpy.reshape

numpy.reshape 函数可以在不改变数据的条件下修改形状,格式如下: numpy.reshape(arr, newshape, order=‘C’)

  • arr:要修改形状的数组
  • newshape:整数或者整数数组,新的形状应当兼容原有形状
  • order:‘C’ – 按行,‘F’ – 按列,‘A’ – 原顺序,‘k’ – 元素在内存中的出现顺序
>>> a = np.arange(8)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7])
>>> b = a.reshape(4,2)
>>> b
array([[0, 1],
       [2, 3],
       [4, 5],
       [6, 7]])

>>> np.reshape(a,(4,2))
array([[0, 1],
       [2, 3],
       [4, 5],
       [6, 7]])

>>> np.reshape(a,(4,2),order='F')
array([[0, 4],
       [1, 5],
       [2, 6],
       [3, 7]])

numpy.ndarray.flat

numpy.ndarray.flat 是一个数组元素迭代器,实例如下:

>>> a = np.arange(9).reshape(3,3)
>>> for row in a:
...     print(row)
[0 1 2]
[3 4 5]
[6 7 8]

对数组中每个元素都进行处理,可以使用flat属性,该属性是一个数组元素迭代器:
>>> for element in a.flat:
...     print (element)
0
1
2
3
4
5
6
7
8

numpy.ndarray.flatten

numpy.ndarray.flatten 返回一份数组拷贝,对拷贝所做的修改不会影响原始数组,格式如下:

ndarray.flatten(order='C')

参数说明:

  • order:‘C’ – 按行,‘F’ – 按列,‘A’ – 原顺序,‘K’ – 元素在内存中的出现顺序。
>>> a = np.arange(8).reshape(2,4)
>>> a
array([[0, 1, 2, 3],
       [4, 5, 6, 7]])

>>> a.flatten()
array([0, 1, 2, 3, 4, 5, 6, 7])

>>> a.flatten(order='F')
array([0, 4, 1, 5, 2, 6, 3, 7])

numpy.ravel

numpy.ravel() 展平的数组元素,顺序通常是"C风格",返回的是数组视图(view,有点类似 C/C++引用reference的意味),修改会影响原始数组。

numpy.ravel(a, order='C')

参数说明:

  • order:‘C’ – 按行,‘F’ – 按列,‘A’ – 原顺序,‘K’ – 元素在内存中的出现顺序。
>>> a = np.arange(8).reshape(2,4)
>>> a
array([[0, 1, 2, 3],
       [4, 5, 6, 7]])

>>> a.ravel()
array([0, 1, 2, 3, 4, 5, 6, 7])
>>> np.ravel(a)
array([0, 1, 2, 3, 4, 5, 6, 7])

>>> np.ravel(a,order='F')
array([0, 4, 1, 5, 2, 6, 3, 7])

翻转数组

  • transpose 对换数组的维度
  • ndarray.T 和 self.transpose() 相同
  • rollaxis 向后滚动指定的轴
  • swapaxes 对换数组的两个轴

numpy.transpose

numpy.transpose 函数用于对换数组的维度,格式如下:

numpy.transpose(arr, axes)

参数说明:

  • arr:要操作的数组
  • axes:整数列表,对应维度,通常所有维度都会对换。0为最外层轴。列表中从左到右为从外到里的轴。如(2,1,0)表示将原数组2轴移到最外层,1轴到中间,0轴移到最里层。
>>> a = np.arange(12).reshape(3,4)
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> np.transpose(a)
>>> a.transpose()
array([[ 0,  4,  8],
       [ 1,  5,  9],
       [ 2,  6, 10],
       [ 3,  7, 11]])

不改变原有的数组。

>>> x = np.arange(6).reshape(1,2,3)
>>> x
array([[[0, 1, 2],
        [3, 4, 5]]])
>>> x.shape
(1, 2, 3)

>>> y =  x.transpose((1,0,2))
>>> y
array([[[0, 1, 2]],

       [[3, 4, 5]]])
>>> y.shape
(2, 1, 3)

>>> y =  x.transpose()
>>> y
array([[[0],
        [3]],

       [[1],
        [4]],

       [[2],
        [5]]])
>>> y.shape
(3, 2, 1)

numpy.ndarray.T 类似 numpy.transpose:

>>> a = np.arange(12).reshape(3,4)
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> a.T
array([[ 0,  4,  8],
       [ 1,  5,  9],
       [ 2,  6, 10],
       [ 3,  7, 11]])

numpy.rollaxis

numpy.rollaxis 函数向后滚动特定的轴到一个特定位置,格式如下:

numpy.rollaxis(arr, axis, start)

参数说明:

  • arr:数组
  • axis:要向后滚动的轴,其它轴的相对位置不会改变,0位最外层轴。
  • start:默认为零,表示完整的滚动。会滚动到特定位置。
>>> a = np.arange(8).reshape(2,2,2)
>>> a
array([[[0, 1],
        [2, 3]],

       [[4, 5],
        [6, 7]]])

>>> np.where(a==6)
(array([1], dtype=int64), array([1], dtype=int64), array([0], dtype=int64))
>>> a[1,1,0]
6

将轴 2 滚动到轴 0(宽度到深度)
调用 rollaxis 函数:
>>> b = np.rollaxis(a,2,0)
>>> b
array([[[0, 2],
        [4, 6]],

       [[1, 3],
        [5, 7]]])
和transpose()效果相同;
>>> a.transpose((2,0,1))
array([[[0, 2],
        [4, 6]],

       [[1, 3],
        [5, 7]]])
查看元素 a[1,1,0],即 6 的坐标,变成 [0, 1, 1]
>>> np.where(b==6)
(array([0], dtype=int64), array([1], dtype=int64), array([1], dtype=int64))

将轴 2 滚动到轴 1:(宽度到高度)
调用 rollaxis 函数:
>>> c = np.rollaxis(a,2,1)
>>> c
array([[[0, 2],
        [1, 3]],

       [[4, 6],
        [5, 7]]])
>>> a.transpose((0,2,1))
array([[[0, 2],
        [1, 3]],

       [[4, 6],
        [5, 7]]])
查看元素 a[1,1,0],即 6 的坐标,变成 [1, 0, 1]
最后的 0 和 它前面的 1 对换位置
>>> np.where(c==6)
(array([1], dtype=int64), array([0], dtype=int64), array([1], dtype=int64))

numpy.swapaxes

numpy.swapaxes 函数用于交换数组的两个轴,格式如下:

numpy.swapaxes(arr, axis1, axis2)
  • arr:输入的数组
  • axis1:对应第一个轴的整数
  • axis2:对应第二个轴的整数
>>> a = np.arange(8).reshape(2,2,2)
>>> a
array([[[0, 1],
        [2, 3]],

       [[4, 5],
        [6, 7]]])

现在交换轴 0(深度方向)到轴 2(宽度方向)
调用 swapaxes 函数后的数组:
>>> np.swapaxes(a, 2, 0)
array([[[0, 4],
        [2, 6]],

       [[1, 5],
        [3, 7]]])

修改数组维度

  • broadcast 产生模仿广播的对象
  • broadcast_to 将数组广播到新形状
  • expand_dims 扩展数组的形状
  • squeeze 从数组的形状中删除一维条目

numpy.broadcast

numpy.broadcast 用于模仿广播的对象,它返回一个对象,该对象封装了将一个数组广播到另一个数组的结果。

该函数使用两个数组作为输入参数,如下实例:

import numpy as np
x = np.array([[1], [2], [3]])
y = np.array([4, 5, 6]) 
对 y 广播 x
b = np.broadcast(x,y)
它拥有 iterator 属性,基于自身组件的迭代器元组 
>>> for i in b:
...     print(i)
(1, 4)
(1, 5)
(1, 6)
(2, 4)
(2, 5)
(2, 6)
(3, 4)
(3, 5)
(3, 6)

广播对象的形状:
>>> b.shape
(3, 3)

手动使用 broadcast 将 x 与 y 相加
>>> b = np.broadcast(x,y)
>>> c = np.empty(b.shape)
>>> c.flat = [u + v for (u,v) in b]
>>> c
array([[5., 6., 7.],
       [6., 7., 8.],
       [7., 8., 9.]])
>>> x+y
array([[5, 6, 7],
       [6, 7, 8],
       [7, 8, 9]])

numpy.broadcast_to

numpy.broadcast_to 函数将数组广播到新形状。它在原始数组上返回只读视图。 它通常不连续。 如果新形状不符合 NumPy 的广播规则,该函数可能会抛出ValueError。

numpy.broadcast_to(array, shape, subok)
import numpy as np
 
>>> a = np.arange(4).reshape(1,4)
>>> a
array([[0, 1, 2, 3]])
>>> np.broadcast_to(a,(4,4))
array([[0, 1, 2, 3],
       [0, 1, 2, 3],
       [0, 1, 2, 3],
       [0, 1, 2, 3]])

numpy.expand_dims

numpy.expand_dims 函数通过在指定位置插入新的轴来扩展数组形状,函数格式如下:

 numpy.expand_dims(arr, axis)

参数说明:

  • arr:输入数组
  • axis:新轴插入的位置
import numpy as np
 
>>> x = np.array(([1,2],[3,4]))
>>> x
array([[1, 2],
       [3, 4]])
在位置 0 插入轴
>>> y = np.expand_dims(x, axis = 0)  # 0轴是最外层轴
>>> y
array([[[1, 2],
        [3, 4]]])
数组 x 和 y 的形状:
>>> x.shape,y.shape
((2, 2), (1, 2, 2))

在位置 1 插入轴
>>> y = np.expand_dims(x, axis = 1)
>>> y
array([[[1, 2]],

       [[3, 4]]])
>>> x.shape, y.shape
((2, 2), (2, 1, 2))

numpy.squeeze

numpy.squeeze 函数从给定数组的形状中删除一维的条目,函数格式如下:

numpy.squeeze(arr, axis)
参数说明:
-arr:输入数组

  • axis:整数或整数元组,用于选择形状中一维条目的子集
import numpy as np
>>> x = np.arange(9).reshape(1,3,3)
>>> x
array([[[0, 1, 2],
        [3, 4, 5],
        [6, 7, 8]]])
>>> y = np.squeeze(x)
>>> y
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
数组 x 和 y 的形状:
>>> x.shape, y.shape
((1, 3, 3), (3, 3))

连接数组

  • concatenate 连接沿现有轴的数组序列
  • stack 沿着新的轴加入一系列数组。
  • hstack 水平堆叠序列中的数组(列方向)
  • vstack 竖直堆叠序列中的数组(行方向)

numpy.concatenate

numpy.concatenate 函数用于沿指定轴连接相同形状的两个或多个数组,格式如下:

numpy.concatenate((a1, a2, ...), axis)

参数说明:

  • a1, a2, …:相同类型的数组
  • axis:沿着它连接数组的轴,默认为 0
>>> a = np.array([[1,2],[3,4]])
>>> b = np.array([[5,6],[7,8]])

沿轴 0 连接两个数组:
>>> np.concatenate((a,b))
array([[1, 2],
       [3, 4],
       [5, 6],
       [7, 8]])

沿轴 1 连接两个数组:
>>> np.concatenate((a,b),axis = 1)
array([[1, 2, 5, 6],
       [3, 4, 7, 8]])

numpy.stack

numpy.stack 函数用于沿新轴连接数组序列,格式如下:

numpy.stack(arrays, axis)

参数说明:

  • arrays相同形状的数组序列
  • axis:返回数组中的轴,输入数组沿着它来堆叠
>>> a = np.array([[1,2],[3,4]])
>>> b = np.array([[5,6],[7,8]])

沿轴 0 堆叠两个数组:
>>> np.stack((a,b),0)
array([[[1, 2],
        [3, 4]],

       [[5, 6],
        [7, 8]]])

沿轴 1 堆叠两个数组:
>>> np.stack((a,b),1)
array([[[1, 2],
        [5, 6]],

       [[3, 4],
        [7, 8]]])

沿轴 2 堆叠两个数组:
>> np.stack((a,b),2)
array([[[1, 5],
        [2, 6]],

       [[3, 7],
        [4, 8]]])

numpy.hstack

numpy.hstack 是 numpy.stack 函数的变体,它通过水平堆叠来生成数组。

>>> a = np.array([[1,2],[3,4]])
>>> b = np.array([[5,6],[7,8]])
>>> np.hstack((a,b))
array([[1, 2, 5, 6],
       [3, 4, 7, 8]])

和concatenate一样
>>> np.concatenate((a,b),axis = 1)
array([[1, 2, 5, 6],
       [3, 4, 7, 8]])

numpy.vstack

numpy.vstack 是 numpy.stack 函数的变体,它通过垂直堆叠来生成数组。

>>> a = np.array([[1,2],[3,4]])
>>> b = np.array([[5,6],[7,8]])
>>> np.vstack((a,b))
array([[1, 2],
       [3, 4],
       [5, 6],
       [7, 8]])

和concatenate一样
>>> np.concatenate((a,b))
array([[1, 2],
       [3, 4],
       [5, 6],
       [7, 8]])

分割数组

  • split 将一个数组分割为多个子数组
  • hsplit 将一个数组水平分割为多个子数组(按列)
  • vsplit 将一个数组垂直分割为多个子数组(按行)

numpy.split

numpy.split 函数沿特定的轴将数组分割为子数组,格式如下:

numpy.split(ary, indices_or_sections, axis)

参数说明:

  • ary:被分割的数组
  • indices_or_sections:如果是一个整数,就用该数平均切分,如果是一个数组,为沿轴切分的位置(左开右闭)
  • axis:设置沿着哪个方向进行切分,默认为 0,横向切分,即水平方向。为 1 时,纵向切分,即竖直方向。
>>> a = np.arange(9)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8])

将数组分为三个大小相等的子数组:
>>> np.split(a,3)
[array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]

将数组在一维数组中表明的位置分割:
>>> np.split(a,[2,5,7])
[array([0, 1]), array([2, 3, 4]), array([5, 6]), array([7, 8])]

axis 为 0 时在水平方向分割,axis 为 1 时在垂直方向分割:

>>> a = np.arange(16).reshape(4, 4)
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])

默认分割(0轴):
>>> np.split(a,2)
[array([[0, 1, 2, 3],
       [4, 5, 6, 7]]), array([[ 8,  9, 10, 11],
       [12, 13, 14, 15]])]

沿垂直方向分割:
>>> np.split(a,2,1)
[array([[ 0,  1],
       [ 4,  5],
       [ 8,  9],
       [12, 13]]), array([[ 2,  3],
       [ 6,  7],
       [10, 11],
       [14, 15]])]

numpy.hsplit

numpy.hsplit 函数用于水平分割数组,通过指定要返回的相同形状的数组数量来拆分原数组。

>>> harr = np.floor(10 * np.random.random((2, 6)))
>>> harr
array([[5., 5., 1., 1., 5., 4.],
       [2., 1., 8., 2., 3., 1.]])
拆分后
>>> np.hsplit(harr, 3)
[array([[5., 5.],
       [2., 1.]]), array([[1., 1.],
       [8., 2.]]), array([[5., 4.],
       [3., 1.]])]
使用split在1轴拆分
>>> np.split(harr,3,1)
[array([[5., 5.],
       [2., 1.]]), array([[1., 1.],
       [8., 2.]]), array([[5., 4.],
       [3., 1.]])]

numpy.vsplit

numpy.vsplit 沿着垂直轴分割,其分割方式与hsplit用法相同。

>>> a = np.arange(16).reshape(4,4)
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])
竖直分割:
>>> np.vsplit(a,2)
[array([[0, 1, 2, 3],
       [4, 5, 6, 7]]), array([[ 8,  9, 10, 11],
       [12, 13, 14, 15]])]
>>> np.split(a,2,0)
[array([[0, 1, 2, 3],
       [4, 5, 6, 7]]), array([[ 8,  9, 10, 11],
       [12, 13, 14, 15]])]

数组元素的添加与删除

  • resize 返回指定形状的新数组
  • append 将值添加到数组末尾
  • insert 沿指定轴将值插入到指定下标之前
  • delete 删掉某个轴的子数组,并返回删除后的新数组
  • unique 查找数组内的唯一元素

numpy.resize

numpy.resize 函数返回指定大小的新数组。

如果新数组大小大于原始大小,则包含原始数组中的元素的副本。

numpy.resize(arr, shape)

参数说明:

  • arr:要修改大小的数组
  • shape:返回数组的新形状
>>> a = np.array([[1,2,3],[4,5,6]])
>>> a
array([[1, 2, 3],
       [4, 5, 6]])
>>> np.resize(a, (3,2))
array([[1, 2],
       [3, 4],
       [5, 6]])

修改第二个数组的大小:
>>> np.resize(a,(3,3))
array([[1, 2, 3],
       [4, 5, 6],
       [1, 2, 3]])

>>> np.resize(a,(3,5))
array([[1, 2, 3, 4, 5],
       [6, 1, 2, 3, 4],
       [5, 6, 1, 2, 3]])

numpy.append

numpy.append 函数在数组的末尾添加值。 追加操作会分配整个数组,并把原来的数组复制到新数组中。 此外,输入数组的维度必须匹配否则将生成ValueError。

append 函数返回的始终是一个一维数组。

numpy.append(arr, values, axis=None)

参数说明:

  • arr:输入数组
  • values:要向arr添加的值,需要和arr形状相同(除了要添加的轴)
  • axis:默认为 None。当axis无定义时,是横向加成,返回总是为一维数组!当axis有定义的时候,分别为0和1的时候。当axis有定义的时候,分别为0和1的时候(列数要相同)。当axis为1时,数组是加在右边(行数要相同)。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值