Python notes1- numpy 部分

开始对python比较重要的模块以及自己经常忘记的部分进行整理,先来对numpy来进行一个学习整理。首先numpy(Numerical Python)是python非常重要的一个库,也是我学习工作过程中经常用到的一个程序库,主要用来进行数组或者矩阵的计算,适合进行线性代数计算。
numpy经常和SciPy(Scientific Python)和 Matplotlib(用于绘图)一起使用,基本包括了MATLAB的大部分功能,这种组合广泛用于替代 MatLab,是一个强大的科学计算环境。
整篇笔记的参考资料来源于菜鸟教程1

1 数组属性

1.1 基本介绍

NumPy 数组的维数就是轴的数量,即数组的维度,在 NumPy中,每一个线性的数组称为是一个轴(axis),也就是维度(dimensions)。比如说,二维数组相当于是两个一维数组,其中第一个一维数组中每个元素又是一个一维数组。所以一维数组就是 NumPy 中的轴(axis),第一个轴相当于是底层数组,第二个轴是底层数组里的数组。而轴的数量就是数组的维数。
很多时候可以声明 axis。axis=0,表示沿着第 0 轴进行操作,即对每一列进行操作;axis=1,表示沿着第1轴进行操作,即对每一行进行操作。
NumPy 的数组中比较重要 ndarray 对象属性有:
1 ndarray.ndim:轴的数量或维度的数量
2 ndarray.shape:数组的维度,对于矩阵,n 行 m 列
3 ndarray.size:数组元素的总个数,相当于 .shape 中 n*m 的值
4 ndarray.dtype:ndarray对象的元素类型
5 ndarray.itemsize:ndarray对象中每个元素的大小,以字节为单位
6 ndarray.flags:ndarray对象的内存信息
7 ndarray.real:ndarray元素的实部
8 ndarray.imag:ndarray元素的虚部
9 ndarray.data:包含实际数组元素的缓冲区,由于一般通过数组的索引获取元素,所以通常不需要使用这个属性。

1.2 ndarray.ndim

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

1.3 ndarray.shape

ndarray.shape 表示数组的维度,返回一个元组,这个元组的长度就是维度的数目,即 ndim 属性。比如,一个二维数组,其维度表示"行数"和"列数"。
ndarray.shape 也可以用于调整数组大小。

import numpy as np   
a = np.array([[1,2,3],[4,5,6]])  
print (a.shape)
###### 调整数组大小
import numpy as np  
a = np.array([[1,2,3],[4,5,6]]) 
a.shape = (3,2)  
print (a)
### 由两行三列矩阵或数组被输出为三行两列矩阵或者数组
###### NumPy 也提供了 reshape 函数来调整数组大小。
a = np.array([[1,2,3],[4,5,6]]) 
b = a.reshape(3,2)  
print (b)

1.4 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) 
### 输出1
###### 数组的 dtype 现在为 float64(八个字节) 
y = np.array([1,2,3,4,5], dtype = np.float64)  
print (y.itemsize)
### 输出8

1.5 ndarray.flags

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

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

2 创建N维数组对象

2.1 通用类型

numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
### object:数组或嵌套的数列
### dtype:数组元素的数据类型,可选,后面会具体讲
### copy:对象是否需要复制,可选
### order:创建数组的样式,C为行方向,F为列方向,A为任意方向(默认)
### subok:默认返回一个与基类类型一致的数组
### ndmin:指定生成数组的最小维度
###### e.g.
import numpy as np 
a = np.array([1,2,3])  
print (a)

2.2 创建未初始化的指定数据类型与形状的数组

numpy.empty(shape, dtype = float, order = 'C')
### shape:数组形状,即定义多少行多少列
### dtype:数据类型,可选,后面会具体讲
### order:有"C"和"F"两个选项,分别代表行优先和列优先,在计算机内存中的存储元素的顺序,也就是说决定从行开始读起,还是列开始读起
###### e.g.
import numpy as np 
x = np.empty([4,3], dtype = int) 
print(x)
### 输出结果的数组元素为随机值,因为它们未初始化。

2.3 创建数组元素为零的指定形状的数组

numpy.zeros(shape, dtype = float, order = 'C')
###### e.g.
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)

2.4 创建数组元素为1的指定形状的数组

可以创建元素为零的数组,同样也可以创建元素为1的数组。

numpy.ones(shape, dtype = None, order = 'C')
### order:'C' 用于 C 的行数组,或者 'F' 用于 FORTRAN 的列数组
###### e.g.
import numpy as np
# 默认为浮点数
x = np.ones(5) 
print(x)
# 自定义类型
x = np.ones([2,2], dtype = int) # 通过python运行,发现[2,2]和(2,2)输出的结果是一样的
print(x)

3 数组元素的数据类型

3.1 基本简介

numpy 支持的数据类型比 Python 内置的类型要多很多,基本上可以和 C 语言的数据类型对应上,其中部分类型对应为 Python 内置的类型。下表列举了常用 NumPy 基本类型。

名称 描述
bool_ 布尔型数据类型(True 或者 False)
int_ 默认的整数类型(类似于 C 语言中的 long,int32 或 int64)
intc 与 C 的 int 类型一样,一般是 int32 或 int 64
intp 用于索引的整数类型(类似于 C 的 ssize_t,一般情况下仍然是 int32 或 int64)
int8 字节(-128 to 127)
int16 整数(-32768 to 32767)
int32 整数(-2147483648 to 2147483647)
int64 整数(-9223372036854775808 to 9223372036854775807)
uint8 无符号整数(0 to 255)
uint16 无符号整数(0 to 65535)
uint32 无符号整数(0 to 4294967295)
uint64 无符号整数(0 to 18446744073709551615)
float_ float64 类型的简写
float16 半精度浮点数,包括:1 个符号位,5 个指数位,10 个尾数位
float32 单精度浮点数,包括:1 个符号位,8 个指数位,23 个尾数位
float64 双精度浮点数,包括:1 个符号位,11 个指数位,52 个尾数位
complex_ complex128 类型的简写,即 128 位复数
complex64 复数,表示双 32 位浮点数(实数部分和虚数部分)
complex128 复数,表示双 64 位浮点数(实数部分和虚数部分)

3.2 数据类型对象 (dtype)

数据类型对象是用来描述与数组对应的内存区域如何使用,这依赖如下几个方面:
1 数据的类型(整数,浮点数或者 Python 对象)
2 数据的大小(例如, 整数使用多少个字节存储)
3 数据的字节顺序(小端法或大端法)
4 在结构化类型的情况下,字段的名称、每个字段的数据类型和每个字段所取的内存块的部分
5 如果数据类型是子数组,它的形状和数据类型
字节顺序是通过对数据类型预先设定"<“或”>“来决定的。”<“意味着小端法(最小值存储在最小的地址,即低位组放在最前面)。”>"意味着大端法(最重要的字节存储在最小的地址,即高位组放在最前面)。
dtype 对象是使用以下语法构造的:

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

3.3 Example

import numpy as np
# 使用标量类型
dt = np.dtype(np.int32)
print(dt)
### ------------------------------------------------------------------------------
import numpy as np
# int8, int16, int32, int64 四种数据类型可以使用字符串 'i1', 'i2','i4','i8' 代替
dt = np.dtype('i4')
print(dt)
### ------------------------------------------------------------------------------
import numpy as np
# 字节顺序标注
dt = np.dtype(')
print(dt)
### ------------------------------------------------------------------------------
# 将数据类型应用于 ndarray 对象
import numpy as np
dt = np.dtype([('age',np.int8)]) 
a = np.array([(10,),(20,),(30,)], dtype = dt) 
print(a) ### output: [(10,) (20,) (30,)]
print(a['age']) ### output: [10 20 30]
### ------------------------------------------------------------------------------
import numpy as np
student = np.dtype([('name','S20'), ('age', 'i1'), ('marks', 'f4')]) 
a = np.array([('abc', 21, 50),('xyz', 18, 75)], dtype = student) 
print(a) ### output: [('abc', 21, 50.0) ('xyz', 18, 75.0)]
print(a['name']) ### output: ['abc' 'xyz']

3.4 唯一定义内建类型的字符代码(待进一步理解)

每个内建类型都有一个唯一定义它的字符代码,如下:

字符 对应类型
b 布尔型
i (有符号) 整型
u 无符号整型 integer
f 浮点型
c 复数浮点型
m timedelta(时间间隔)
M datetime(日期时间)
O (Python) 对象
S, a (byte-)字符串
U Unicode
V 原始数据 (void)

4 更多创建数组的方法

4.1 NumPy从已有的数组创建数组

4.1.1 numpy.asarray

numpy.asarray(a, dtype = None, order = None)
### a:任意形式的输入参数,可以是,列表, 列表的元组, 元组, 元组的元组, 元组的列表,多维数组
######----------------------------------------------------------------------------
### e.g.
### 将列表转换为 ndarray
x =  [1,2,3] 
a = np.asarray(x)  
print (a)  ### output: [1  2  3]
### 将元组列表转换为 ndarray
x =  [(1,2,3),(4,5)] 
a = np.asarray(x)  
print (a)  ### output: [(1, 2, 3) (4, 5)]
### 同时还可以设置 dtype 参数
x =  [1,2,3] 
a = np.asarray(x, dtype =  float)  
print (a)  ### output: [ 1.  2.  3.]

4.1.2 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:可以是任意对象,会以流的形式读入
### count:读取的数据数量,默认为-1,读取所有数据
### offset:读取的起始位置,默认为0
######----------------------------------------------------------------------------
### e.g.
### python 3.0 edition
import numpy as np  
s =  b'Hello World' 
a = np.frombuffer(s, dtype =  'S1')  
print (a) ### output: [b'H' b'e' b'l' b'l' b'o' b' ' b'W' b'o' b'r' b'l' b'd']
### python 2.0 edition
s =  'Hello World'
a = np.frombuffer(s, dtype =  'S1')
print (a) ### output: ['H' 'e' 'l' 'l' 'o' ' ' 'W' 'o' 'r' 'l' 'd']

4.1.3 numpy.fromiter

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

numpy.fromiter(iterable, dtype, count=-1)
### iterable:可迭代对象
### count:读取的数据数量,默认为-1,读取所有数据
######----------------------------------------------------------------------------
### e.g.
# 使用 range 函数创建列表对象  
list=range(5)
it=iter(list) 
# 使用迭代器创建 ndarray 
x=np.fromiter(it, dtype=float)
print(x) ### output: [0. 1. 2. 3. 4.]

4.2 NumPy 从数值范围创建数组

4.2.1 numpy.arange

numpy 包中的使用 arange 函数创建数值范围并返回 ndarray 对象

numpy.arange(start, stop, step, dtype)
### start:起始值,默认为0
### stop:终止值(不包含)
### step:步长,默认为1
###### e.g.
import numpy as np
x = np.arange(5)  
print (x) ### output: [0  1  2  3  4]
### 设置了起始值、终止值及步长
import numpy as np
x = np.arange(10,20,2)  
print (x) ### output: [10  12  14  16  18]

4.2.2 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 时,生成的数组中会显示间距,反之不显示。
###### e.g.
### 该实例用到三个参数,设置起始点为 1 ,终止点为 10,数列个数为 10
import numpy as np
a = np.linspace(1,10,10)
print(a) ### output: [ 1.  2.  3.  4.  5.  6.  7.  8.  9. 10.]
### 设置元素全部是1的等差数列
import numpy as np
a = np.linspace(1,1,10)
print(a) ### output: [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
### 该实例设置间距
a =np.linspace(1,10,10,retstep= True)
print(a)
# 拓展例子
b =np.linspace(1,10,10).reshape([10,1])
print(b)
### output:
### (array([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10.]), 1.0)
### [[ 1.]
###  [ 2.]
###  [ 3.]
###  [ 4.]
###  [ 5.]
###  [ 6.]
###  [ 7.]
###  [ 8.]
###  [ 9.]
###  [10.]]

4.2.3 numpy.logspace

numpy.logspace 函数用于创建一个于等比数列

np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
### start:序列的起始值为:base ** start
### stop:序列的终止值为:base ** stop。如果endpoint为true,该值包含于数列中
### num:要生成的等步长的样本数量,默认为50
### endpoint:该值为 true 时,数列中中包含stop值,反之不包含,默认是True。
### base:对数 log 的底数。
###### e.g. 
import numpy as np
# 默认底数是 10
a = np.logspace(1.0,  2.0, num =  10)  
print (a) 
### output:
### [ 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) ### output: [  1.   2.   4.   8.  16.  32.  64. 128. 256. 512.]

5 索引

5.1 切片和索引基本操作

ndarray对象的内容可以通过索引或切片来访问和修改,与 Python 中 list 的切片操作一样。
ndarray 数组可以基于 0 - n 的下标进行索引,切片对象可以通过内置的 slice 函数,并设置 start, stop 及 step 参数进行,从原数组中切割出一个新数组。
以下通过一系列例子对索引基本操作进行基本介绍。

import numpy as np
######----------------------------------------------------------------------------
### 利用slice()函数
a = np.arange(10)
s = slice(2,7,2)   # 从索引2开始到索引7停止,间隔为2
print (a[s]) # or print(a[slice(2,7,2)])
### output: [2  4  6]
######----------------------------------------------------------------------------
a = np.arange(10)  
b = a[2:7:2]   # 从索引2开始到索引7停止,间隔为 2
print(b)
### output: [2  4  6]
######----------------------------------------------------------------------------
a = np.arange(10)  # [0 1 2 3 4 5 6 7 8 9]
b = a[5] 
print(b)
### output: 5
######----------------------------------------------------------------------------
### 应用于多维数组
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
print(a)
# 从某个索引处开始切割
print('从数组索引 a[1:] 处开始切割')
print(a[1:])
### output:
### [[1 2 3]
###  [3 4 5]
###  [4 5 6]]
### 从数组索引 a[1:] 处开始切割
### [[3 4 5]
###  [4 5 6]]
######----------------------------------------------------------------------------
### 切片还可以包括省略号 …,来使选择元组的长度与数组的维度相同。 如果在行位置使用省略号,它将返回包含行中元素的 ndarray。
a = np.array([[1,2,3],[3,4,5],[4,5,6]])  
print (a[...,1])   # 第2列元素
print (a[1,...])   # 第2行元素
print (a[...,1:])  # 第2列及剩下的所有元素
### output:
### [2 4 5]
### [3 4 5]
### [[2 3]
###  [4 5]
###  [5 6]]

5.2 NumPy 高级索引

5.2.1 整数数组索引

### 获取数组中(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) # output: [1  4  5]
######----------------------------------------------------------------------------
x = np.array([[  0,  1,  2],[  3,  4,  5],[  6,  7,  8],[  9,  10,  11]])  
rows = np.array([[0,0],[3,3]]) 
cols = np.array([[0,2],[0,2]]) 
y = x[rows,cols]  
print (y)
### output:
### [[ 0  2]
###  [ 9 11]]
### OR
y = x[[0,0,3,3],[0,2,0,2]] 
print (y) ### output: [ 0  2  9 11]
######----------------------------------------------------------------------------
a = np.array([[1,2,3], [4,5,6],[7,8,9]])
b = a[1:3, 1:3]
c = a[1:3,[1,2]]
d = a[...,1:]
print(b)
print(c)
print(d)
### output:
### [[5 6]
###  [8 9]]
### [[5 6]
###  [8 9]]
### [[2 3]
###  [5 6]
###  [8 9]]

5.2.2 布尔索引

我们可以通过一个布尔数组来索引目标数组。
布尔索引通过布尔运算(如:比较运算符)来获取符合指定条件的元素的数组。

### 获取大于5的元素
import numpy as np  
x = np.array([[  0,  1,  2],[  3,  4,  5],[  6,  7,  8],[  9,  10,  11]])  
print ('我们的数组是:')
print (x)
print ('\n')
# 现在我们会打印出大于 5 的元素  
print  ('大于 5 的元素是:')
print (x[x > 5])
### output:
### 我们的数组是:
### [[ 0  1  2]
###  [ 3  4  5]
###  [ 6  7  8]
###  [ 9 10 11]]
### 
### 
### 大于 5 的元素是:
### [ 6  7  8  9 10 11]
######----------------------------------------------------------------------------
### 使用 ~(取补运算符)来过滤 NaN。
a = np.array([np.nan,  1,2,np.nan,3,4,5])  
print (a[~np.isnan(a)]) # np.isnan() and np.nan() 函数
### output: [ 1.   2.   3.   4.   5.]
######----------------------------------------------------------------------------
### 演示如何从数组中过滤掉非复数元素。
a = np.array([1,  2+6j,  5,  3.5+5j])  
print (a[np.iscomplex(a)]) # np.iscomplex() 函数
### output: [2.0+6.j  3.5+5.j]

5.2.3 花式索引

花式索引指的是利用整数数组进行索引。
花式索引根据索引数组的值作为目标数组的某个轴的下标来取值。对于使用一维整型数组作为索引,如果目标是一维数组,那么索引的结果就是对应位置的元素;如果目标是二维数组,那么就是对应下标的行。
花式索引跟切片不一样,它总是将数据复制到新数组中。

###### 传入顺序索引数组
import numpy as np 
x=np.arange(32).reshape((8,4))
print (x[[4,2,1,7]])
### output:
### [[16 17 18 19]
###  [ 8  9 10 11]
###  [ 4  5  6  7]
###  [28 29 30 31]]

###### 传入倒序索引数组
x=np.arange(32).reshape((8,4))
print (x[[-4,-2,-1,-7]])
### output:
### [[16 17 18 19]
###  [24 25 26 27]
###  [28 29 30 31]
###  [ 4  5  6  7]]

###### 传入多个索引数组(要使用np.ix_)
x=np.arange(32).reshape((8,4))
print (x[np.ix_([1,5,7,2],[0,3,1,2])])
### output:
### [[ 4  7  5  6]
###  [20 23 21 22]
###  [28 31 29 30]
###  [ 8 11  9 10]]
### notes:
### np.xi_ 中输入两个列表,则第一个列表存的是待提取元素的行标,第二个列表存的是待提取元素的列标,第
### 一个列表中的每个元素都会遍历第二个列表中的每个值,构成新矩阵的一行元素。

6 NumPy 广播(Broadcast)

广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式, 对数组的算术运算通常在相应的元素上进行。
如果两个数组 a 和 b 形状相同,即满足 a.shape == b.shape,那么 a*b 的结果就是 a 与 b 数组对应位相乘。这要求维数相同,且各维度的长度相同。
当运算中的 2 个数组的形状不同时,numpy 将自动触发广播机制。如:
4x3 的二维数组与长为 3 的一维数组相加,等效于把数组 b 在二维上重复 4 次再运算。

### e.g.
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)
### output:
### [[ 1  2  3]
###  [11 12 13]
###  [21 22 23]
###  [31 32 33]]
###### 等价于
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)
### output:
### [[ 1  2  3]
###  [11 12 13]
###  [21 22 23]
###  [31 32 33]]

广播的规则:
1 让所有输入数组都向其中形状最长的数组看齐,形状中不足的部分都通过在前面加 1 补齐。
2 输出数组的形状是输入数组形状的各个维度上的最大值。
3 如果输入数组的某个维度和输出数组的对应维度的长度相同或者其长度为 1 时,这个数组能够用来计算,否则出错。
4 当输入数组的某个维度的长度为 1 时,沿着此维度运算时都用此维度上的第一组值。
简单理解:对两个数组,分别比较他们的每一个维度(若其中一个数组没有当前维度则忽略),满足:
1 数组拥有相同形状。
2 当前维度的值相等。
3 当前维度的值有一个是 1。
4 若条件不满足,抛出 “ValueError: frames are not aligned” 异常。
理解title():tile() 函数,就是将原矩阵横向、纵向地复制。

tile(mat, (1, 4))  ### 列复制为原来的四倍
np.ones((2,3)) 
### 等效于 
np.tile(1., (2,3))
######----------------------------------------------------------------------------
np.zeros((2,3)) 
### 等效于 
np.tile(0., (2,3)) 

7 迭代数组

7.1 基本操作

NumPy 迭代器对象 numpy.nditer 提供了一种灵活访问一个或者多个数组元素的方式。迭代器最基本的任务的可以完成对数组元素的访问。即使用nditer()来进行迭代

import numpy as np
a = np.arange(6).reshape(2,3)
print ('原始数组是:')
print (a)
print ('\n')
print ('迭代输出元素:')
for x in np.nditer(a):
    print (x, end=", " )
### output:
### 原始数组是:
### [[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)
for x in np.nditer(a.T): # a.T 代表矩阵的转置
    print (x, end=", " )
print ('\n') 
for x in np.nditer(a.T.copy(order='C')):  ### copy() function
    print (x, end=", " )
### output:
### 0, 1, 2, 3, 4, 5, 
### 
### 0, 3, 1, 4, 2, 5, 

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

7.2 控制遍历顺序

for x in np.nditer(a, order=‘F’):Fortran order,即是列序优先;for x in np.nditer(a.T, order=‘C’):C order,即是行序优先。

import numpy as np 
a = np.arange(0,60,5) 
a = a.reshape(3,4)  
print ('原始数组是:') 
print (a) 
print ('\n') 
print ('原始数组的转置是:') 
b = a.T 
print (b) 
print ('\n') 
print ('以 C 风格顺序排序:') 
c = b.copy(order='C')  
print (c)
for x in np.nditer(c):  
    print (x, end=", " )
print  ('\n') 
print  ('以 F 风格顺序排序:')
c = b.copy(order='F')  
print (c)
for x in np.nditer(c):  
    print (x, end=", " )
### output:
### 原始数组是:
### [[ 0  5 10 15]
###  [20 25 30 35]
###  [40 45 50 55]]
### 
### 
### 原始数组的转置是:
### [[ 0 20 40]
###  [ 5 25 45]
###  [10 30 50]
###  [15 35 55]]
### 
### 
### 以 C 风格顺序排序:
### [[ 0 20 40]
###  [ 5 25 45]
###  [10 30 50]
###  [15 35 55]]
### 0, 20, 40, 5, 25, 45, 10, 30, 50, 15, 35, 55, 
### 
### 以 F 风格顺序排序:
### [[ 0 20 40]
###  [ 5 25 45]
###  [10 30 50]
###  [15 35 55]]
### 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55,
######----------------------------------------------------------------------------
### 可以通过显式设置,来强制 nditer 对象使用某种顺序
a = np.arange(0,60,5) 
a = a.reshape(3,4)  
print ('原始数组是:')
print (a)
print ('\n')
print ('以 C 风格顺序排序:')
for x in np.nditer(a, order =  'C'):  
    print (x, end=", " )
print ('\n')
print ('以 F 风格顺序排序:')
for x in np.nditer(a, order =  'F'):  
    print (x, end=", " )
### output:
### 原始数组是:
### [[ 0  5 10 15]
###  [20 25 30 35]
###  [40 45 50 55]]
### 
### 
### 以 C 风格顺序排序:
### 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 
### 
### 以 F 风格顺序排序:
### 0, 20, 40, 5, 25, 45, 10, 30, 50, 15, 35, 55,

7.3 修改数组中元素的值

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

import numpy as np 
a = np.arange(0,60,5) 
a = a.reshape(3,4)  
print ('原始数组是:')
print (a)
print ('\n')
for x in np.nditer(a, op_flags=['readwrite']): 
    x[...]=2*x 
print ('修改后的数组是:')
print (a)
### output:
### 原始数组是:
### [[ 0  5 10 15]
###  [20 25 30 35]
###  [40 45 50 55]]
### 
### 
### 修改后的数组是:
### [[  0  10  20  30]
###  [ 40  50  60  70]
###  [ 80  90 100 110]]

7.4 使用外部循环

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

参数 描述
c_index 可以跟踪 C 顺序的索引
f_index 可以跟踪 Fortran 顺序的索引
multi-index 每次迭代可以跟踪一种索引类型
external_loop 给出的值是具有多个值的一维数组,而不是零维数组
### "external_loop"迭代器遍历对应于每列,并组合为一维数组。
import numpy as np 
a = np.arange(0,60,5) 
a = a.reshape(3,4)  
print ('原始数组是:')
print (a)
print ('\n')
print ('修改后的数组是:')
for x in np.nditer(a, flags =  ['external_loop'], order =  'F'):  
   print (x, end=", " )
### output:
### 原始数组是:
### [[ 0  5 10 15]
###  [20 25 30 35]
###  [40 45 50 55]]
### 
### 
### 修改后的数组是:
### [ 0 20 40], [ 5 25 45], [10 30 50], [15 35 55],

7.5 广播迭代

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

import numpy as np  
a = np.arange(0,60,5) 
a = a.reshape(3,4)  
print  ('第一个数组为:')
print (a)
print  ('\n')
print ('第二个数组为:')
b = np.array([1,  2,  3,  4], dtype =  int)  
print (b)
print ('\n')
print ('修改后的数组为:')
for x,y in np.nditer([a,b]):  
    print ("%d:%d"  %  (x,y), end=", " )
### output:
### 第一个数组为:
### [[ 0  5 10 15]
###  [20 25 30 35]
###  [40 45 50 55]]
### 
### 
### 第二个数组为:
### [1 2 3 4]
### 
### 
### 修改后的数组为:
### 0:1, 5:2, 10:3, 15:4, 20:1, 25:2, 30:3, 35:4, 40:1, 45:2, 50:3, 55:4,

8 数组的基本处理

8.1 修改数组形状

8.1.1 numpy.reshape

numpy.reshape(arr, newshape, order='C')
### arr:要修改形状的数组
### newshape:整数或者整数数组,新的形状应当兼容原有形状
### order:'C' -- 按行,'F' -- 按列,'A' -- 原顺序,'k' -- 元素在内存中的出现顺序。
###### e.g.
import numpy as np 
a = np.arange(8)
print ('原始数组:')
print (a)
b = a.reshape(4,2)
print ('修改后的数组:')
print (b)
### OR
b = np.reshape(a,(4,2))
print ('修改后的数组:')
print (b)
### output:
### 原始数组:
### [0 1 2 3 4 5 6 7]
### 修改后的数组:
### [[0 1]
###  [2 3]
###  [4 5]
###  [6 7]]
### 修改后的数组:
### [[0 1]
###  [2 3]
###  [4 5]
###  [6 7]]

8.1.2 numpy.ndarray.flat

numpy.ndarray.flat 是一个数组元素迭代器

import numpy as np 
a = np.arange(9).reshape(3,3) 
print ('原始数组:')
for row in a:
    print (row) 
#对数组中每个元素都进行处理,可以使用flat属性,该属性是一个数组元素迭代器:
print ('迭代后的数组:')
for element in a.flat:
    print (element)
### output:
### 原始数组:
### [0 1 2]
### [3 4 5]
### [6 7 8]
### 迭代后的数组:
### 0
### 1
### 2
### 3
### 4
### 5
### 6
### 7
### 8

8.1.3 numpy.ndarray.flatten

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

ndarray.flatten(order='C')
### order:'C' -- 按行,'F' -- 按列,'A' -- 原顺序,'K' -- 元素在内存中的出现顺序。
###### e.g.
import numpy as np 
a = np.arange(8).reshape(2,4) 
print ('原数组:')
print (a)
# 默认按行 
print ('展开的数组:')
print (a.flatten())
print ('以 F 风格顺序展开的数组:')
print (a.flatten(order = 'F'))
### output:
### 原数组:
### [[0 1 2 3]
###  [4 5 6 7]]
### 展开的数组:
### [0 1 2 3 4 5 6 7]
### 以 F 风格顺序展开的数组:
### [0 4 1 5 2 6 3 7]

8.1.4 numpy.ravel

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

numpy.ravel(a, order='C')
### order:'C' -- 按行,'F' -- 按列,'A' -- 原顺序,'K' -- 元素在内存中的出现顺序。
###### e.g.
import numpy as np
a = np.arange(8).reshape(2,4)
print ('原数组:')
print (a)
print ('调用 ravel 函数之后:')
print (a.ravel())
print ('以 F 风格顺序调用 ravel 函数之后:')
print (a.ravel(order = 'F'))
### output:
### 原数组:
### [[0 1 2 3]
###  [4 5 6 7]]
### 调用 ravel 函数之后:
### [0 1 2 3 4 5 6 7]
### 以 F 风格顺序调用 ravel 函数之后:
### [0 4 1 5 2 6 3 7]

8.2 翻转数组

8.2.1 numpy.transpose & numpy.ndarray.T

numpy.transpose 函数用于对换数组的维度,类似于矩阵的转置。

numpy.transpose(arr, axes)
### arr:要操作的数组
### axes:整数列表,对应维度,通常所有维度都会对换。
###### e.g.
import numpy as np 
a = np.arange(12).reshape(3,4) 
print ('原数组:')
print (a ) 
print ('对换数组:')
print (np.transpose(a))
### output:
### 原数组:
### [[ 0  1  2  3]
###  [ 4  5  6  7]
###  [ 8  9 10 11]]
### 对换数组:
### [[ 0  4  8]
###  [ 1  5  9]
###  [ 2  6 10]
###  [ 3  7 11]]
###### numpy.ndarray.T 类似 numpy.transpose
a = np.arange(12).reshape(3,4) 
print ('原数组:')
print (a)
print ('转置数组:')
print (a.T)
### output:
### 原数组:
### [[ 0  1  2  3]
###  [ 4  5  6  7]
###  [ 8  9 10 11]]
### 转置数组:
### [[ 0  4  8]
###  [ 1  5  9]
###  [ 2  6 10]
###  [ 3  7 11]]

8.2.2 numpy.rollaxis

numpy.rollaxis 函数向后滚动特定的轴到一个特定位置

numpy.rollaxis(arr, axis, start)
### arr:数组
### axis:要向后滚动的轴,其它轴的相对位置不会改变
### start:默认为零,表示完整的滚动。会滚动到特定位置
###### e.g.
import numpy as np 
# 创建了三维的 ndarray
a = np.arange(8).reshape(2,2,2) 
print ('原数组:')
print (a)
# 将轴 2 滚动到轴 0(宽度到深度)
print ('调用 rollaxis 函数:')
print (np.rollaxis(a,2))
# 将轴 0 滚动到轴 1:(宽度到高度) 
print ('调用 rollaxis 函数:')
print (np.rollaxis(a,2,1))
### output:
### 原数组:
### [[[0 1]
###   [2 3]]
### 
###  [[4 5]
###   [6 7]]]
### 调用 rollaxis 函数:
### [[[0 2]
###   [4 6]]
### 
###  [[1 3]
###   [5 7]]]
### 调用 rollaxis 函数:
### [[[0 2]
###   [1 3]]
### 
###  [[4 6]
###   [5 7]]]

8.2.3 numpy.swapaxes

numpy.swapaxes 函数用于交换数组的两个轴。

numpy.swapaxes(arr, axis1, axis2)
### arr:输入的数组
### axis1:对应第一个轴的整数
### axis2:对应第二个轴的整数
###### e.g.
import numpy as np
# 创建了三维的 ndarray
a = np.arange(8).reshape(2,2,2)
print ('原数组:')
print (a)
# 现在交换轴 0(深度方向)到轴 2(宽度方向)
print ('调用 swapaxes 函数后的数组:')
print (np.swapaxes(a, 2, 0))
### output:
### 原数组:
### [[[0 1]
###   [2 3]]
### 
###  [[4 5]
###   [6 7]]]
### 调用 swapaxes 函数后的数组:
### [[[0 4]
###   [2 6]]
### 
###  [[1 5]
###   [3 7]]]

8.3 修改数组维度

8.3.1 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 属性,基于自身组件的迭代器元组 
print ('对 y 广播 x:')
r,c = b.iters 
# Python3.x 为 next(context) ,Python2.x 为 context.next()
print (next(r), next(c))
print (next(r), next(c))
# shape 属性返回广播对象的形状
print ('广播对象的形状:')
print (b.shape)
print ('\n')
# 手动使用 broadcast 将 x 与 y 相加
b = np.broadcast(x,y)
c = np.empty(b.shape) 
print ('手动使用 broadcast 将 x 与 y 相加:')
print (c.shape)
c.flat = [u + v for (u,v) in b] 
print ('调用 flat 函数:')
print (c)
# 获得了和 NumPy 内建的广播支持相同的结果 
print ('x 与 y 的和:')
print (x + y)

### output:
### 对 y 广播 x:
### 1 4
### 1 5
### 广播对象的形状:
### (3, 3)
### 手动使用 broadcast 将 x 与 y 相加:
### (3, 3)
### 调用 flat 函数:
### [[5. 6. 7.]
###  [6. 7. 8.]
###  [7. 8. 9.]]
### x 与 y 的和:
### [[5 6 7]
###  [6 7 8]
###  [7 8 9]]

8.3.2 numpy.broadcast_to

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

numpy.broadcast_to(array, shape, subok)
###### e.g.
import numpy as np 
a = np.arange(4).reshape(1,4) 
print ('原数组:')
print (a) 
print ('调用 broadcast_to 函数之后:')
print (np.broadcast_to(a,(4,4)))
### output:
### 原数组:
### [[0 1 2 3]]
### 调用 broadcast_to 函数之后:
### [[0 1 2 3]
###  [0 1 2 3]
###  [0 1 2 3]
###  [0 1 2 3]]

8.3.3 numpy.expand_dims

numpy.expand_dims 函数通过在指定位置插入新的轴来扩展数组形状

numpy.expand_dims(arr, axis)
### arr:输入数组
### axis:新轴插入的位置
###### e.g.
import numpy as np 
x = np.array(([1,2],[3,4]))
print ('数组 x:')
print (x)
y = np.expand_dims(x, axis = 0)
print ('数组 y:')
print (y) 
print ('数组 x 和 y 的形状:')
print (x.shape, y.shape)
# 在位置 1 插入轴
y = np.expand_dims(x, axis = 1)
print ('在位置 1 插入轴之后的数组 y:')
print (y) 
print ('x.ndim 和 y.ndim:')
print (x.ndim,y.ndim)
print ('x.shape 和 y.shape:')
print (x.shape, y.shape)
### output:
### 数组 x:
### [[1 2]
###  [3 4]]
### 数组 y:
### [[[1 2]
###   [3 4]]]
### 数组 x 和 y 的形状:
### (2, 2) (1, 2, 2)
### 在位置 1 插入轴之后的数组 y:
### [[[1 2]]
### 
###  [[3 4]]]
### x.ndim 和 y.ndim:
### 2 3
### x.shape 和 y.shape:
### (2, 2) (2, 1, 2)

8.3.4 numpy.squeeze

numpy.squeeze 函数从给定数组的形状中删除一维的条目

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

8.4 连接数组

8.4.1 numpy.concatenate

numpy.concatenate 函数用于沿指定轴连接相同形状的两个或多个数组。

numpy.concatenate((a1, a2, ...), axis)
### a1, a2, ...:相同类型的数组
### axis:沿着它连接数组的轴,默认为 0
###### e.g.
import numpy as np 
a = np.array([[1,2],[3,4]]) 
print ('第一个数组:')
print (a)
b = np.array([[5,6],[7,8]]) 
print ('第二个数组:')
print (b)
# 两个数组的维度相同 
print ('沿轴 0 连接两个数组:')
print (np.concatenate((a,b))) 
print ('沿轴 1 连接两个数组:')
print (np.concatenate((a,b),axis = 1))
### output:
### 第一个数组:
### [[1 2]
###  [3 4]]
### 第二个数组:
### [[5 6]
###  [7 8]]
### 沿轴 0 连接两个数组:
### [[1 2]
###  [3 4]
###  [5 6]
###  [7 8]]
### 沿轴 1 连接两个数组:
### [[1 2 5 6]
###  [3 4 7 8]]

8.4.2 numpy.stack

numpy.stack 函数用于沿新轴连接数组序列。

numpy.stack(arrays, axis)
### arrays: 相同形状的数组序列
### axis:返回数组中的轴,输入数组沿着它来堆叠
###### e.g.
import numpy as np 
a = np.array([[1,2],[3,4]]) 
print ('第一个数组:')
print (a)
b = np.array([[5,6],[7,8]]) 
print ('第二个数组:')
print (b)
print ('沿轴 0 堆叠两个数组:')
print (np.stack((a,b),0)) 
print ('沿轴 1 堆叠两个数组:')
print (np.stack((a,b),1))
### output:
### 第一个数组:
### [[1 2]
###  [3 4]]
### 第二个数组:
### [[5 6]
###  [7 8]]
### 沿轴 0 堆叠两个数组:
### [[[1 2]
###   [3 4]]
### 
###  [[5 6]
###   [7 8]]]
### 沿轴 1 堆叠两个数组:
### [[[1 2]
###   [5 6]]
### 
###  [[3 4]
###   [7 8]]]

8.4.3 numpy.hstack

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

import numpy as np 
a = np.array([[1,2],[3,4]]) 
print ('第一个数组:')
print (a)
b = np.array([[5,6],[7,8]])
print ('第二个数组:')
print (b)
print ('水平堆叠:')
c = np.hstack((a,b))
print (c)
### output:
### 第一个数组:
### [[1 2]
###  [3 4]]
### 第二个数组:
### [[5 6]
###  [7 8]]
### 水平堆叠:
### [[1 2 5 6]
###  [3 4 7 8]]

8.4.4 numpy.vstack

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

import numpy as np
a = np.array([[1,2],[3,4]]) 
print ('第一个数组:')
print (a)
b = np.array([[5,6],[7,8]])
print ('第二个数组:')
print (b)
print ('竖直堆叠:')
c = np.vstack((a,b))
print (c)
### output: 
### 第一个数组:
### [[1 2]
###  [3 4]]
### 第二个数组:
### [[5 6]
###  [7 8]]
### 竖直堆叠:
### [[1 2]
###  [3 4]
###  [5 6]
###  [7 8]]

8.5 分割数组

8.5.1 numpy.split

numpy.split 函数沿特定的轴将数组分割为子数组。

numpy.split(ary, indices_or_sections, axis)
### ary:被分割的数组
### indices_or_sections:果是一个整数,就用该数平均切分,如果是一个数组,为沿轴切分的位置(左开右闭)
### axis:沿着哪个维度进行切向,默认为0,横向切分。为1时,纵向切分
###### e.g.
import numpy as np
a = np.arange(9)
print ('第一个数组:')
print (a)
print ('将数组分为三个大小相等的子数组:')
b = np.split(a,3)
print (b)
print ('将数组在一维数组中表明的位置分割:')
b = np.split(a,[4,7])
print (b)
### output:
### 第一个数组:
### [0 1 2 3 4 5 6 7 8]
### 将数组分为三个大小相等的子数组:
### [array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]
### 将数组在一维数组中表明的位置分割:
### [array([0, 1, 2, 3]), array([4, 5, 6]), array([7, 8])]

8.5.2 numpy.hsplit

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

import numpy as np 
harr = np.floor(10 * np.random.random((2, 6)))
print ('原array:')
print(harr)
print ('拆分后:')
print(np.hsplit(harr, 3))
### output:
### 原array:
### [[4. 7. 6. 3. 2. 6.]
###  [6. 3. 6. 7. 9. 7.]]
### 拆分后:
### [array([[4., 7.],
###        [6., 3.]]), array([[6., 3.],
###        [6., 7.]]), array([[2., 6.],
###        [9., 7.]])]

8.5.3 numpy.vsplit

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

import numpy as np 
a = np.arange(16).reshape(4,4)
print ('第一个数组:')
print (a)
print ('竖直分割:')
b = np.vsplit(a,2)
print (b)
### output:
### 第一个数组:
### [[ 0  1  2  3]
###  [ 4  5  6  7]
###  [ 8  9 10 11]
###  [12 13 14 15]]
### 竖直分割:
### [array([[0, 1, 2, 3],
###        [4, 5, 6, 7]]), array([[ 8,  9, 10, 11],
###        [12, 13, 14, 15]])]

8.6 数组元素的添加与删除

8.6.1 numpy.resize

numpy.resize 函数返回指定大小的新数组。如果新数组大小大于原始大小,则包含原始数组中的元素的副本。

numpy.resize(arr, shape)
### arr:要修改大小的数组
### shape:返回数组的新形状
###### e.g.
import numpy as np 
a = np.array([[1,2,3],[4,5,6]]) 
print ('第一个数组:')
print (a)
print ('第一个数组的形状:')
print (a.shape)
b = np.resize(a, (3,2)) 
print ('第二个数组:')
print (b)
print ('第二个数组的形状:')
print (b.shape)
# 要注意 a 的第一行在 b 中重复出现,因为尺寸变大了
print ('修改第二个数组的大小:')
b = np.resize(a,(3,3))
print (b)
### output:
### 第一个数组:
### [[1 2 3]
###  [4 5 6]]
### 第一个数组的形状:
### (2, 3)
### 第二个数组:
### [[1 2]
###  [3 4]
###  [5 6]]
### 第二个数组的形状:
### (3, 2)
### 修改第二个数组的大小:
### [[1 2 3]
###  [4 5 6]
###  [1 2 3]]

8.6.2 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时,数组是加在右边(行数要相同)
###### e.g.
import numpy as np
a = np.array([[1,2,3],[4,5,6]]) 
print ('第一个数组:')
print (a) 
print ('向数组添加元素:')
print (np.append(a, [7,8,9]))
print ('沿轴 0 添加元素:')
print (np.append(a, [[7,8,9]],axis = 0)) 
print ('沿轴 1 添加元素:')
print (np.append(a, [[5,5,5],[7,8,9]],axis = 1))
### output:
### 第一个数组:
### [[1 2 3]
###  [4 5 6]]
### 向数组添加元素:
### [1 2 3 4 5 6 7 8 9]
### 沿轴 0 添加元素:
### [[1 2 3]
###  [4 5 6]
###  [7 8 9]]
### 沿轴 1 添加元素:
### [[1 2 3 5 5 5]
###  [4 5 6 7 8 9]]

8.6.3 numpy.insert

numpy.insert 函数在给定索引之前,沿给定轴在输入数组中插入值。
如果值的类型转换为要插入,则它与输入数组不同。 插入没有原地的,函数会返回一个新数组。 此外,如果未提供轴,则输入数组会被展开。

numpy.insert(arr, obj, values, axis)
### arr:输入数组
### obj:在其之前插入值的索引
### values:要插入的值
### axis:沿着它插入的轴,如果未提供,则输入数组会被展开
###### e.g.
import numpy as np 
a = np.array([[1,2],[3,4],[5,6]]) 
print ('第一个数组:')
print (a)
print ('未传递 Axis 参数。 在插入之前输入数组会被展开。')
print (np.insert(a,3,[11,12]))
print ('传递了 Axis 参数。 会广播值数组来配输入数组。')
print ('沿轴 0 广播:')
print (np.insert(a,1,[11],axis = 0)) 
print ('沿轴 1 广播:')
print (np.insert(a,1,11,axis = 1))
### output:
### 第一个数组:
### [[1 2]
###  [3 4]
###  [5 6]]
### 未传递 Axis 参数。 在插入之前输入数组会被展开。
### [ 1  2  3 11 12  4  5  6]
### 传递了 Axis 参数。 会广播值数组来配输入数组。
### 沿轴 0 广播:
### [[ 1  2]
###  [11 11]
###  [ 3  4]
###  [ 5  6]]
### 沿轴 1 广播:
### [[ 1 11  2]
###  [ 3 11  4]
###  [ 5 11  6]]

8.6.4 numpy.delete

numpy.delete 函数返回从输入数组中删除指定子数组的新数组。 与 insert() 函数的情况一样,如果未提供轴参数,则输入数组将展开。

Numpy.delete(arr, obj, axis)
### arr:输入数组
### obj:可以被切片,整数或者整数数组,表明要从输入数组删除的子数组
### axis:沿着它删除给定子数组的轴,如果未提供,则输入数组会被展开
###### e.g.
import numpy as np 
a = np.arange(12).reshape(3,4) 
print ('第一个数组:')
print (a) 
print ('未传递 Axis 参数。 在插入之前输入数组会被展开。')
print (np.delete(a,5)) 
print ('删除第二列:')
print (np.delete(a,1,axis = 1))
print ('包含从数组中删除的替代值的切片:')
a = np.array([1,2,3,4,5,6,7,8,9,10])
print (np.delete(a, np.s_[::2]))
### output:
### 第一个数组:
### [[ 0  1  2  3]
###  [ 4  5  6  7]
###  [ 8  9 10 11]]
### 未传递 Axis 参数。 在插入之前输入数组会被展开。
### [ 0  1  2  3  4  6  7  8  9 10 11]
### 删除第二列:
### [[ 0  2  3]
###  [ 4  6  7]
###  [ 8 10 11]]
### 包含从数组中删除的替代值的切片:
### [ 2  4  6  8 10]

8.6.5 numpy.unique

numpy.unique 函数用于去除数组中的重复元素。

numpy.unique(arr, return_index, return_inverse, return_counts)
### arr:输入数组,如果不是一维数组则会展开
### return_index:如果为true,返回新列表元素在旧列表中的位置(下标),并以列表形式储
### return_inverse:如果为true,返回旧列表元素在新列表中的位置(下标),并以列表形式储
### return_counts:如果为true,返回去重数组中的元素在原数组中的出现次数
###### e.g.
import numpy as np
a = np.array([5,2,6,2,7,5,6,8,2,9])
print ('第一个数组:')
print (a)
print ('第一个数组的去重值:')
u = np.unique(a)
print (u)
print ('去重数组的索引数组:')
u,indices = np.unique(a, return_index = True)
print (indices) 
print ('我们可以看到每个和原数组下标对应的数值:')
print (a) 
print ('去重数组的下标:')
u,indices = np.unique(a,return_inverse = True)
print (u)
print ('下标为:')
print (indices)
print ('使用下标重构原数组:')
print (u[indices]) 
print ('返回去重元素的重复数量:')
u,indices = np.unique(a,return_counts = True)
print (u)
print (indices)
### output:
### 第一个数组:
### [5 2 6 2 7 5 6 8 2 9]
### 第一个数组的去重值:
### [2 5 6 7 8 9]
### 去重数组的索引数组:
### [1 0 2 4 7 9]
### 我们可以看到每个和原数组下标对应的数值:
### [5 2 6 2 7 5 6 8 2 9]
### 去重数组的下标:
### [2 5 6 7 8 9]
### 下标为:
### [1 0 2 0 3 1 2 4 0 5]
### 使用下标重构原数组:
### [5 2 6 2 7 5 6 8 2 9]
### 返回去重元素的重复数量:
### [2 5 6 7 8 9]
### [3 2 2 1 1 1]

9 NumPy 位运算

二进制运算,用得少,需要的时候查看链接即可。

10 Numpy 常用函数

10.1 字符串函数

1 numpy.char.add()

import numpy as np 
print ('连接两个字符串:')
print (np.char.add(['hello'],[' xyz']))
print ('连接示例:')
print (np.char.add(['hello', 'hi'],[' abc', ' xyz']))
### output
### 连接两个字符串:
### ['hello xyz']
### 连接示例:
### ['hello abc' 'hi xyz']

2 numpy.char.multiply()

import numpy as np  
print (np.char.multiply('Runoob ',3))
### output
### Runoob Runoob Runoob 

3 numpy.char.center()

import numpy as np  
# np.char.center(str , width,fillchar) :
# str: 字符串,width: 长度,fillchar: 填充字符
print (np.char.center('Runoob', 20,fillchar = '*'))
### output
### *******Runoob*******

4 numpy.char.capitalize()

import numpy as np  
print (np.char.capitalize('runoob'))
### output
### Runoob

5 numpy.char.title()
numpy.char.title() 函数将字符串的每个单词的第一个字母转换为大写。

import numpy as np
print (np.char.title('i like runoob'))
### output
### I Like Runoob

6 numpy.char.lower() & numpy.char.upper()
numpy.char.lower() 函数对数组的每个元素转换为小写。它对每个元素调用 str.lower。
numpy.char.upper() 函数对数组的每个元素转换为大写。它对每个元素调用 str.upper。

import numpy as np 
#操作数组
print (np.char.lower(['RUNOOB','GOOGLE'])) 
# 操作字符串
print (np.char.lower('RUNOOB'))
#操作数组
print (np.char.upper(['runoob','google'])) 
# 操作字符串
print (np.char.upper('runoob'))
### output
### ['runoob' 'google']
### runoob
### ['RUNOOB' 'GOOGLE']
### RUNOOB

7 numpy.char.split()
numpy.char.split() 通过指定分隔符对字符串进行分割,并返回数组。默认情况下,分隔符为空格。

import numpy as np  
# 分隔符默认为空格
print (np.char.split ('i like runoob?'))
# 分隔符为 .
print (np.char.split ('www.runoob.com', sep = '.'))
### output
### ['i', 'like', 'runoob?']
### ['www', 'runoob', 'com']

8 numpy.char.splitlines()
numpy.char.splitlines() 函数以换行符作为分隔符来分割字符串,并返回数组。

import numpy as np  
# 换行符 \n
print (np.char.splitlines('i\nlike runoob?')) 
print (np.char.splitlines('i\rlike runoob?'))
### \n,\r,\r\n 都可用作换行符。

9 numpy.char.strip()
numpy.char.strip() 函数用于移除开头或结尾处的特定字符。

import numpy as np  
# 移除字符串头尾的 a 字符
print (np.char.strip('ashok arunooba','a')) 
# 移除数组元素头尾的 a 字符
print (np.char.strip(['arunooba','admin','java'],'a'))
### output
### shok arunoob
### ['runoob' 'dmin' 'jav']

10 numpy.char.join()
numpy.char.join() 函数通过指定分隔符来连接数组中的元素或字符串

import numpy as np  
# 操作字符串
print (np.char.join(':','runoob'))
# 指定多个分隔符操作数组元素
print (np.char.join([':','-'],['runoob','google']))
### output
### r:u:n:o:o:b
### ['r:u:n:o:o:b' 'g-o-o-g-l-e']

11 numpy.char.replace()
numpy.char.replace() 函数使用新字符串替换字符串中的所有子字符串。

import numpy as np  
print (np.char.replace ('i like runoob', 'oo', 'cc'))
### output
### i like runccb

12 numpy.char.encode()
numpy.char.encode() 函数对数组中的每个元素调用 str.encode 函数。 默认编码是 utf-8,可以使用标准 Python 库中的编解码器。

import numpy as np  
a = np.char.encode('runoob', 'cp500') 
print (a)
### output
### b'\x99\xa4\x95\x96\x96\x82'

13 numpy.char.decode()
numpy.char.decode() 函数对编码的元素进行 str.decode() 解码。

import numpy as np  
a = np.char.encode('runoob', 'cp500') 
print (a)
print (np.char.decode(a,'cp500'))
### output
### b'\x99\xa4\x95\x96\x96\x82'
### runoob

10.2 数学函数

1 三角函数
NumPy 提供了标准的三角函数:sin()、cos()、tan()。

import numpy as np 
a = np.array([0,30,45,60,90])
print ('不同角度的正弦值:')
# 通过乘 pi/180 转化为弧度  
print (np.sin(a*np.pi/180))
print ('数组中角度的余弦值:')
print (np.cos(a*np.pi/180))
print ('数组中角度的正切值:')
print (np.tan(a*np.pi/180))
### output
### 不同角度的正弦值:
### [0.         0.5        0.70710678 0.8660254  1.        ]
### 数组中角度的余弦值:
### [1.00000000e+00 8.66025404e-01 7.07106781e-01 5.00000000e-01
###  6.12323400e-17]
### 数组中角度的正切值:
### [0.00000000e+00 5.77350269e-01 1.00000000e+00 1.73205081e+00
###  1.63312394e+16]

arcsin,arccos,和 arctan 函数返回给定角度的 sin,cos 和 tan 的反三角函数。这些函数的结果可以通过 numpy.degrees() 函数将弧度转换为角度。

import numpy as np
a = np.array([0,30,45,60,90])  
print ('含有正弦值的数组:'); sin = np.sin(a*np.pi/180); print (sin)
print ('计算角度的反正弦,返回值以弧度为单位:'); inv = np.arcsin(sin); print (inv)
print ('通过转化为角度制来检查结果:'); print (np.degrees(inv)); print ('\n')
print ('arccos 和 arctan 函数行为类似:'); cos = np.cos(a*np.pi/180); print (cos)
print ('反余弦:'); inv = np.arccos(cos); print (inv)
print ('角度制单位:'); print (np.degrees(inv))
print ('tan 函数:'); tan = np.tan(a*np.pi/180); print (tan)
print ('反正切:'); inv = np.arctan(tan); print (inv)
print ('角度制单位:');print (np.degrees(inv))
### output:
### 含有正弦值的数组:
### [0.         0.5        0.70710678 0.8660254  1.        ]
### 计算角度的反正弦,返回值以弧度为单位:
### [0.         0.52359878 0.78539816 1.04719755 1.57079633]
### 通过转化为角度制来检查结果:
### [ 0. 30. 45. 60. 90.]
### arccos 和 arctan 函数行为类似:
### [1.00000000e+00 8.66025404e-01 7.07106781e-01 5.00000000e-01
###  6.12323400e-17]
### 反余弦:
### [0.         0.52359878 0.78539816 1.04719755 1.57079633]
### 角度制单位:
### [ 0. 30. 45. 60. 90.]
### tan 函数:
### [0.00000000e+00 5.77350269e-01 1.00000000e+00 1.73205081e+00
###  1.63312394e+16]
### 反正切:
### [0.         0.52359878 0.78539816 1.04719755 1.57079633]
### 角度制单位:
### [ 0. 30. 45. 60. 90.]

2 舍入函数

numpy.around(a,decimals)
### a: 数组
### decimals: 舍入的小数位数。 默认值为0。 如果为负,整数将四舍五入到小数点左侧的位置
###### example
import numpy as np 
a = np.array([1.0,5.55,  123,  0.567,  25.532])  
print  ('原数组:')
print (a)
print ('舍入后:')
print (np.around(a))
print (np.around(a, decimals =  1))
print (np.around(a, decimals =  -1))
### output
### 原数组:
### [  1.      5.55  123.      0.567  25.532]
### 舍入后:
### [  1.   6. 123.   1.  26.]
### [  1.    5.6 123.    0.6  25.5]
### [  0.  10. 120.   0.  30.]

3 numpy.floor()
numpy.floor() 返回小于或者等于指定表达式的最大整数,即向下取整。

import numpy as np
 a = np.array([-1.7,  1.5,  -0.2,  0.6,  10])
print ('提供的数组:')
print (a)
print ('修改后的数组:')
print (np.floor(a))
### output
### 提供的数组:
### [-1.7  1.5 -0.2  0.6 10. ]
### 修改后的数组:
### [-2.  1. -1.  0. 10.]

4 numpy.ceil()
numpy.ceil() 返回大于或者等于指定表达式的最小整数,即向上取整。

import numpy as np 
a = np.array([-1.7,  1.5,  -0.2,  0.6,  10])  
print  ('提供的数组:')
print (a)
print ('修改后的数组:')
print (np.ceil(a))
### output
### 提供的数组:
### [-1.7  1.5 -0.2  0.6 10. ]
### 修改后的数组:
### [-1.  2. -0.  1. 10.]

10.3 算术函数

1 基本加减乘除函数:add(),subtract(),multiply() 和 divide()。

import numpy as np 
a = np.arange(9, dtype = np.float_).reshape(3,3)  
print ('第一个数组:'); print (a)
print ('第二个数组:'); b = np.array([10,10,10])  print (b)
print ('两个数组相加:'); print (np.add(a,b))
print ('两个数组相减:'); print (np.subtract(a,b))
print ('两个数组相乘:'); print (np.multiply(a,b))
print ('两个数组相除:'); print (np.divide(a,b))
### output
### 第一个数组:
### [[0. 1. 2.]
###  [3. 4. 5.]
###  [6. 7. 8.]]
### 第二个数组:
### [10 10 10]
### 两个数组相加:
### [[10. 11. 12.]
###  [13. 14. 15.]
###  [16. 17. 18.]]
### 两个数组相减:
### [[-10.  -9.  -8.]
### [ -7.  -6.  -5.]
###  [ -4.  -3.  -2.]]
### 两个数组相乘:
### [[ 0. 10. 20.]
###  [30. 40. 50.]
###  [60. 70. 80.]]
### 两个数组相除:
### [[0.  0.1 0.2]
###  [0.3 0.4 0.5]
###  [0.6 0.7 0.8]]

2 numpy.reciprocal()
numpy.reciprocal() 函数返回参数逐元素的倒数。如 1/4 倒数为 4/1。

import numpy as np  
a = np.array([0.25,  1.33,  1,  100])  
print ('我们的数组是:'); print (a)
print ('调用 reciprocal 函数:'); print (np.reciprocal(a))
### output:
### 我们的数组是:
### [  0.25   1.33   1.   100.  ]
### 调用 reciprocal 函数:
### [4.        0.7518797 1.        0.01     ]

3 numpy.power()
numpy.power() 函数将第一个输入数组中的元素作为底数,计算它与第二个输入数组中相应元素的幂。

import numpy as np  
a = np.array([10,100,1000])  
print ('我们的数组是;'); print (a)
print ('调用 power 函数:'); print (np.power(a,2))
print ('第二个数组:'); b = np.array([1,2,3]); print (b)
print ('再次调用 power 函数:'); print (np.power(a,b))
### output:
### 我们的数组是;
### [  10  100 1000]
### 调用 power 函数:
### [    100   10000 1000000]
### 第二个数组:
### [1 2 3]
### 再次调用 power 函数:
### [        10      10000 1000000000]

4 numpy.mod()
numpy.mod() 计算输入数组中相应元素的相除后的余数。 函数 numpy.remainder() 也产生相同的结果。

import numpy as np
a = np.array([10,20,30]); b = np.array([3,5,7])  
print ('第一个数组:'); print (a)
print ('第二个数组:'); print (b)
print ('调用 mod() 函数:'); print (np.mod(a,b))
print ('调用 remainder() 函数:'); print (np.remainder(a,b))
### output:
### 第一个数组:
### [10 20 30]
### 第二个数组:
### [3 5 7]
### 调用 mod() 函数:
### [1 0 2]
### 调用 remainder() 函数:
### [1 0 2]

10.4 统计函数

1 numpy.amin() 和 numpy.amax()
numpy.amin() 用于计算数组中的元素沿指定轴的最小值;numpy.amax() 用于计算数组中的元素沿指定轴的最大值。

import numpy as np  
a = np.array([[3,7,5],[8,4,3],[2,4,9]])  
print ('我们的数组是:'); print (a)
print ('调用 amin() 函数:'); print (np.amin(a,1))
print ('再次调用 amin() 函数:'); print (np.amin(a,0))
print ('调用 amax() 函数:'); print (np.amax(a))
print ('再次调用 amax() 函数:'); print (np.amax(a, axis =  0))
### output:
### 我们的数组是:
### [[3 7 5]
###  [8 4 3]
###  [2 4 9]]
### 调用 amin() 函数:
### [3 3 2]
### 再次调用 amin() 函数:
### [2 4 3]
### 调用 amax() 函数:
### 9
### 再次调用 amax() 函数:
### [8 7 9]

2 numpy.ptp()
numpy.ptp()函数计算数组中元素最大值与最小值的差(max - min)。

import numpy as np  
a = np.array([[3,7,5],[8,4,3],[2,4,9]])  
print ('我们的数组是:'); print (a)
print ('调用 ptp() 函数:'); print (np.ptp(a))
print ('沿轴 1 调用 ptp() 函数:'); print (np.ptp(a, axis =  1))
print ('沿轴 0 调用 ptp() 函数:'); print (np.ptp(a, axis =  0))
### output:
### 我们的数组是:
### [[3 7 5]
###  [8 4 3]
###  [2 4 9]]
### 调用 ptp() 函数:
### 7
### 沿轴 1 调用 ptp() 函数:
### [4 5 7]
### 沿轴 0 调用 ptp() 函数:
### [6 3 6]

3 numpy.percentile()
百分位数是统计中使用的度量,表示小于这个值的观察值的百分比。 函数numpy.percentile()接受以下参数。

numpy.percentile(a, q, axis)
### a: 输入数组
### q: 要计算的百分位数,在 0 ~ 100 之间
### axis: 沿着它计算百分位数的轴
###### example
import numpy as np 
a = np.array([[10, 7, 4], [3, 2, 1]])
print ('我们的数组是:'); print (a); print ('调用 percentile() 函数:') 
# 50% 的分位数,就是 a 里排序之后的中位数 
print (np.percentile(a, 50))  
# axis 为 0,在纵列上求
print (np.percentile(a, 50, axis=0))  
# axis 为 1,在横行上求
print (np.percentile(a, 50, axis=1))  
# 保持维度不变
print (np.percentile(a, 50, axis=1, keepdims=True))
### output:
### 我们的数组是:
### [[10  7  4]
###  [ 3  2  1]]
### 调用 percentile() 函数:
### 3.5
### [6.5 4.5 2.5]
### [7. 2.]
### [[7.]
###  [2.]]

4 numpy.median()
numpy.median() 函数用于计算数组 a 中元素的中位数(中值)

import numpy as np  
a = np.array([[30,65,70],[80,95,10],[50,90,60]])  
print ('我们的数组是:'); print (a)
print ('调用 median() 函数:'); print (np.median(a))
print ('沿轴 0 调用 median() 函数:'); print (np.median(a, axis =  0))
print ('沿轴 1 调用 median() 函数:'); print (np.median(a, axis =  1))
### output:
### 我们的数组是:
### [[30 65 70]
###  [80 95 10]
###  [50 90 60]]
### 调用 median() 函数:
### 65.0
### 沿轴 0 调用 median() 函数:
### [50. 90. 60.]
### 沿轴 1 调用 median() 函数:
### [65. 80. 60.]

5 numpy.mean() and numpy.average()
numpy.mean() 函数返回数组中元素的算术平均值。 如果提供了轴,则沿其计算。算术平均值是沿轴的元素的总和除以元素的数量。
numpy.average() 函数根据在另一个数组中给出的各自的权重计算数组中元素的加权平均值。该函数可以接受一个轴参数。 如果没有指定轴,则数组会被展开。加权平均值即将各数值乘以相应的权数,然后加总求和得到总体值,再除以总的单位数。考虑数组[1,2,3,4]和相应的权重[4,3,2,1],通过将相应元素的乘积相加,并将和除以权重的和,来计算加权平均值。

import numpy as np  
a = np.array([[1,2,3],[3,4,5],[4,5,6]])  
print ('我们的数组是:'); print (a)
print ('调用 mean() 函数:'); print (np.mean(a))
print ('沿轴 0 调用 mean() 函数:'); print (np.mean(a, axis =  0))
print ('沿轴 1 调用 mean() 函数:'); print (np.mean(a, axis =  1))
### output:
### 我们的数组是:
### [[1 2 3]
###  [3 4 5]
###  [4 5 6]]
### 调用 mean() 函数:
### 3.6666666666666665
### 沿轴 0 调用 mean() 函数:
### [2.66666667 3.66666667 4.66666667]
### 沿轴 1 调用 mean() 函数:
### [2. 4. 5.]
###### ---------------------------------------------------------------------------
import numpy as np 
a = np.array([1,2,3,4]); print ('我们的数组是:'); print (a)
print ('调用 average() 函数:'); print (np.average(a)) # 不指定权重时相当于 mean 函数
wts = np.array([4,3,2,1])  
print ('再次调用 average() 函数:'); print (np.average(a,weights = wts))
# 如果 returned 参数设为 true,则返回权重的和  
print ('权重的和:');print (np.average([1,2,3,4],weights =  [4,3,2,1], returned=True))
### output:
### 我们的数组是:
### [1 2 3 4]
### 调用 average() 函数:
### 2.5
### 再次调用 average() 函数:
### 2.0
### 权重的和:
### (2.0, 10.0)
###### ---------------------------------------------------------------------------
### 在多维数组中,可以指定用于计算的轴
import numpy as np  
a = np.arange(6).reshape(3,2); print ('我们的数组是:'); print (a)
print ('修改后的数组:');wt = np.array([3,5]);print (np.average(a,axis =1,weights= wt))
print ('修改后的数组:');print (np.average(a, axis = 1, weights = wt, returned =  True))
### output:
### 我们的数组是:
### [[0 1]
###  [2 3]
###  [4 5]]
### 修改后的数组:
### [0.625 2.625 4.625]
### 修改后的数组:
### (array([0.625, 2.625, 4.625]), array([8., 8., 8.]))

6 标准差和方差

import numpy as np; print (np.std([1,2,3,4])) # 标准差
print (np.var([1,2,3,4])) # 方差
### output:
### 1.1180339887498949
### 1.25

10.5 排序、条件刷选函数

1 numpy.sort(): numpy.sort() 函数返回输入数组的排序副本。

numpy.sort(a, axis, kind, order)
### axis: axis=0按列排序,axis=1按行排序
### kind: 默认为'quicksort'(快速排序)
### order: 如果数组包含字段,则是要排序的字段
###### example
import numpy as np  
 
a = np.array([[3,7],[9,1]])  
print ('我们的数组是:')
print (a)
print ('调用 sort() 函数:'); print (np.sort(a))
print ('按列排序:'); print (np.sort(a, axis =  0))
# 在 sort 函数中排序字段 
dt = np.dtype([('name',  'S10'),('age',  int)]) 
a = np.array([("raju",21),("anil",25),("ravi",  17),  ("amar",27)], dtype = dt)  
print ('我们的数组是:'); print (a)
print ('按 name 排序:'); print (np.sort(a, order =  'name'))
### output:
### 我们的数组是:
### [[3 7]
###  [9 1]]
### 调用 sort() 函数:
### [[3 7]
###  [1 9]]
### 按列排序:
### [[3 1]
###  [9 7]]
### 我们的数组是:
### [(b'raju', 21) (b'anil', 25) (b'ravi', 17) (b'amar', 27)]
### 按 name 排序:
### [(b'amar', 27) (b'anil', 25) (b'raju', 21) (b'ravi', 17)]

2 numpy.argsort():numpy.argsort() 函数返回的是数组值从小到大的索引值。

import numpy as np  
x = np.array([3,  1,  2])  
print ('我们的数组是:'); print (x)
print ('对 x 调用 argsort() 函数:'); y = np.argsort(x); print (y)
print ('以排序后的顺序重构原数组:'); print (x[y])
print ('使用循环重构原数组:')
for i in y:  
    print (x[i], end=" ")
### output:
### 我们的数组是:
### [3 1 2]
### 对 x 调用 argsort() 函数:
### [1 2 0]
### 以排序后的顺序重构原数组:
### [1 2 3]
### 使用循环重构原数组
### 1 2 3

3 numpy.lexsort()
numpy.lexsort() 用于对多个序列进行排序。把它想象成对电子表格进行排序,每一列代表一个序列,排序时优先照顾靠后的列。

import numpy as np 
nm =  ('raju','anil','ravi','amar'); dv =  ('f.y.',  's.y.',  's.y.',  'f.y.') 
ind = np.lexsort((dv,nm)); print ('调用 lexsort() 函数:'); print (ind)  
print ('使用这个索引来获取排序后的数据:'); print ([nm[i]  +  ", "  + dv[i]  for i in ind])
### output
### 调用 lexsort() 函数:
### [3 1 0 2]
### 使用这个索引来获取排序后的数据:
### ['amar, f.y.', 'anil, s.y.', 'raju, f.y.', 'ravi, s.y.']

4
msort(a):数组按第一个轴排序,返回排序后的数组副本。np.msort(a) 相等于 np.sort(a, axis=0)。
sort_complex(a):对复数按照先实部后虚部的顺序进行排序。
partition(a, kth[, axis, kind, order]):指定一个数,对数组进行分区。
argpartition(a, kth[, axis, kind, order]):可以通过关键字 kind 指定算法沿着指定轴对数组进行分区。

5 numpy.argmax() 和 numpy.argmin()
numpy.argmax() 和 numpy.argmin()函数分别沿给定轴返回最大和最小元素的索引。

import numpy as np 
a = np.array([[30,40,70],[80,20,10],[50,90,60]])  
print  ('我们的数组是:'); print (a) 
print ('调用 argmax() 函数:'); print (np.argmax(a)) 
print ('展开数组:'); print (a.flatten()) 
print ('沿轴 0 的最大值索引:'); maxindex = np.argmax(a, axis =  0); print (maxindex) 
print ('沿轴 1 的最大值索引:'); maxindex = np.argmax(a, axis =  1); print (maxindex) 
print ('调用 argmin() 函数:'); minindex = np.argmin(a); print (minindex) 
print ('展开数组中的最小值:'); print (a.flatten()[minindex]) 
print ('沿轴 0 的最小值索引:'); minindex = np.argmin(a, axis =  0); print (minindex) 
print ('沿轴 1 的最小值索引:'); minindex = np.argmin(a, axis =  1); print (minindex)
### output:
### 我们的数组是:
### [[30 40 70]
###  [80 20 10]
###  [50 90 60]]
### 调用 argmax() 函数:
### 7
### 展开数组:
### [30 40 70 80 20 10 50 90 60]
### 沿轴 0 的最大值索引:
### [1 2 0]
### 沿轴 1 的最大值索引:
### [2 0 1]
### 调用 argmin() 函数:
### 5
### 展开数组中的最小值:
### 10
### 沿轴 0 的最小值索引:
### [0 1 1]
### 沿轴 1 的最小值索引:
### [0 2 0]

6 numpy.nonzero():numpy.nonzero() 函数返回输入数组中非零元素的索引。

import numpy as np  
a = np.array([[30,40,0],[0,20,10],[50,0,60]]); print ('我们的数组是:'); print (a)
print ('调用 nonzero() 函数:'); print (np.nonzero (a))
### output:
### 我们的数组是:
### [[30 40  0]
###  [ 0 20 10]
###  [50  0 60]]
### 调用 nonzero() 函数:
### (array([0, 0, 1, 1, 2, 2]), array([0, 1, 1, 2, 0, 2]))

7 numpy.where()
numpy.where() 函数返回输入数组中满足给定条件的元素的索引。

import numpy as np 
x = np.arange(9.).reshape(3,  3); print ('我们的数组是:'); print (x)
print ( '大于 3 的元素的索引:'); y = np.where(x >  3); print (y)
print ('使用这些索引来获取满足条件的元素:'); print (x[y])
### output:
### 我们的数组是:
### [[0. 1. 2.]
###  [3. 4. 5.]
###  [6. 7. 8.]]
### 大于 3 的元素的索引:
### (array([1, 1, 2, 2, 2]), array([1, 2, 0, 1, 2]))
### 使用这些索引来获取满足条件的元素:
### [4. 5. 6. 7. 8.]

8 numpy.extract()
numpy.extract() 函数根据某个条件从数组中抽取元素,返回满条件的元素。

import numpy as np  
x = np.arange(9.).reshape(3,  3); print ('我们的数组是:'); print (x)
# 定义条件, 选择偶数元素
condition = np.mod(x,2)  ==  0; print ('按元素的条件值:'); print (condition)
print ('使用条件提取元素:'); print (np.extract(condition, x))
### output:
### 我们的数组是:
### [[0. 1. 2.]
###  [3. 4. 5.]
###  [6. 7. 8.]]
### 按元素的条件值:
### [[ True False  True]
###  [False  True False]
###  [ True False  True]]
### 使用条件提取元素:
### [0. 2. 4. 6. 8.]

11 NumPy 副本和视图(主要判断ID()是否相同)

11.1 无复制

简单的赋值不会创建数组对象的副本。 相反,它使用原始数组的相同id()来访问它。 id()返回 Python 对象的通用标识符,类似于 C 中的指针。此外,一个数组的任何变化都反映在另一个数组上。 例如,一个数组的形状改变也会改变另一个数组的形状。

import numpy as np 
a = np.arange(6)  
print ('我们的数组是:'); print (a)
print ('调用 id() 函数:'); print (id(a))
print ('a 赋值给 b:'); b = a; print (b)
print ('b 拥有相同 id():'); print (id(b))
print ('修改 b 的形状:'); b.shape =  3,2; print (b)
print ('a 的形状也修改了:'); print (a)
### output:
### 我们的数组是:
### [0 1 2 3 4 5]
### 调用 id() 函数:
### 4349302224
### a 赋值给 b:
### [0 1 2 3 4 5]
### b 拥有相同 id():
### 4349302224
### 修改 b 的形状:
### [[0 1]
###  [2 3]
###  [4 5]]
### a 的形状也修改了:
### [[0 1]
###  [2 3]
###  [4 5]]

11.2 ndarray.view() and ndarray.copy()

上面两个函数起到的作用类似。a=np.array([1, 2, 3, 4, 5, 6]); b=a.copy(); b=a.view()

12 NumPy 矩阵库(Matrix)

12.1 matlib.empty()

matlib.empty() 函数返回一个新的矩阵

numpy.matlib.empty(shape, dtype, order)
### shape: 定义新矩阵形状的整数或整数元组
### Dtype: 可选,数据类型
### order: C(行序优先) 或者 F(列序优先)
###### example
import numpy.matlib 
import numpy as np
print (np.matlib.empty((2,2)))
# 填充为随机数据
### output:
### [[-1.49166815e-154 -1.49166815e-154]
###  [ 2.17371491e-313  2.52720790e-212]]

12.2 numpy.matlib.zeros() and numpy.matlib.ones()

numpy.matlib.zeros() 函数创建一个以 0 填充的矩阵。
numpy.matlib.ones()函数创建一个以 1 填充的矩阵。

import numpy.matlib 
import numpy as np 
print (np.matlib.zeros((2,2)))
print (np.matlib.ones((2,2)))
### output:
### [[0. 0.]
###  [0. 0.]]
### [[1. 1.]
###  [1. 1.]]

12.3 numpy.matlib.eye()

numpy.matlib.eye() 函数返回一个矩阵,对角线元素为 1,其他位置为零。

numpy.matlib.eye(n, M,k, dtype)
### n: 返回矩阵的行数
### M: 返回矩阵的列数,默认为 n
### k: 对角线的索引
###### example
import numpy.matlib 
import numpy as np 
print (np.matlib.eye(n =  3, M =  4, k =  0, dtype =  float))
### output:
### [[1. 0. 0. 0.]
###  [0. 1. 0. 0.]
###  [0. 0. 1. 0.]]

12.4 numpy.matlib.identity()

numpy.matlib.identity() 函数返回给定大小的单位矩阵。单位矩阵是个方阵,从左上角到右下角的对角线(称为主对角线)上的元素均为 1,除此以外全都为 0。

import numpy.matlib 
import numpy as np 
# 大小为 5,类型位浮点型
print (np.matlib.identity(5, dtype =  float))
### output:
### [[ 1.  0.  0.  0.  0.] 
###  [ 0.  1.  0.  0.  0.] 
###  [ 0.  0.  1.  0.  0.] 
###  [ 0.  0.  0.  1.  0.] 
###  [ 0.  0.  0.  0.  1.]]

12.5 numpy.matlib.rand()

numpy.matlib.rand() 函数创建一个给定大小的矩阵,数据是随机填充的。

import numpy.matlib 
import numpy as np 
print (np.matlib.rand(3,3))
### output:
### [[0.23966718 0.16147628 0.14162   ]
###  [0.28379085 0.59934741 0.62985825]
###  [0.99527238 0.11137883 0.41105367]]

12.6 Other Functions

import numpy.matlib 
import numpy as np  
i = np.matrix('1,2;3,4')  
print (i)
j = np.asarray(i)  
print (j)
k = np.asmatrix (j)  
print (k)
### output:
### [[1  2] 
###  [3  4]]
### [[1  2] 
###  [3  4]]
### [[1  2] 
###  [3  4]]

13 NumPy 线性代数

13.1 numpy.dot()

numpy.dot() 对于两个一维的数组,计算的是这两个数组对应下标元素的乘积和(数学上称之为内积);对于二维数组,计算的是两个数组的矩阵乘积;对于多维数组,它的通用计算公式如下,即结果数组中的每个元素都是:数组a的最后一维上的所有元素与数组b的倒数第二位上的所有元素的乘积和: dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])。

numpy.dot(a, b, out=None) 
### a : ndarray 数组
### b : ndarray 数组
### out : ndarray, 可选,用来保存dot()的计算结果
###### example
import numpy.matlib
import numpy as np
a = np.array([[1,2],[3,4]])
b = np.array([[11,12],[13,14]])
print(np.dot(a,b))
### output:
### [[37  40] 
###  [85  92]]
### 计算公式:[[1*11+2*13, 1*12+2*14],[3*11+4*13, 3*12+4*14]]

13.2 numpy.vdot()

numpy.vdot() 函数是两个向量的点积。 如果第一个参数是复数,那么它的共轭复数会用于计算。 如果参数是多维数组,它会被展开。

import numpy as np 
a = np.array([[1,2],[3,4]]) 
b = np.array([[11,12],[13,14]])  
# vdot 将数组展开计算内积
print (np.vdot(a,b))
### output:
### 130
### 1*11 + 2*12 + 3*13 + 4*14 = 130

13.3 numpy.inner()

numpy.inner() 函数返回一维数组的向量内积。对于更高的维度,它返回最后一个轴上的和的乘积。

import numpy as np 
print (np.inner(np.array([1,2,3]),np.array([0,1,0])))
# 等价于 1*0+2*1+3*0
### output:
### 2
###----------------------------------------------------------------------------------
a = np.array([[1,2], [3,4]]) 
print ('数组 a:'); print (a)
b = np.array([[11, 12], [13, 14]]) 
print ('数组 b:'); print (b)
print ('内积:'); print (np.inner(a,b))
### output:
### 数组 a:
### [[1 2]
###  [3 4]]
### 数组 b:
### [[11 12]
###  [13 14]]
### 内积:
### [[35 41]
###  [81 95]]
### 计算公式:
### 1*11+2*12, 1*13+2*14 
### 3*11+4*12, 3*13+4*14

13.4 numpy.matmul

numpy.matmul 函数返回两个数组的矩阵乘积。 虽然它返回二维数组的正常乘积,但如果任一参数的维数大于2,则将其视为存在于最后两个索引的矩阵的栈,并进行相应广播。
另一方面,如果任一参数是一维数组,则通过在其维度上附加 1 来将其提升为矩阵,并在乘法之后被去除。

import numpy.matlib 
import numpy as np  
a = [[1,0],[0,1]] 
b = [[4,1],[2,2]] 
print (np.matmul(a,b))
a = [[1,0],[0,1]] 
b = [1,2] 
print (np.matmul(a,b))
print (np.matmul(b,a))
### output:
### [[4  1] 
###  [2  2]]
### [1  2] 
### [1  2]

13.5 numpy.linalg.det():行列式的计算

numpy.linalg.det() 函数计算输入矩阵的行列式。
行列式在线性代数中是非常有用的值。 它从方阵的对角元素计算。 对于 2×2 矩阵,它是左上和右下元素的乘积与其他两个的乘积的差。
换句话说,对于矩阵[[a,b],[c,d]],行列式计算为 ad-bc。 较大的方阵被认为是 2×2 矩阵的组合。

import numpy as np
a = np.array([[1,2], [3,4]])  
print (np.linalg.det(a))
b = np.array([[6,1,1], [4, -2, 5], [2,8,7]]) 
print (b)
print (np.linalg.det(b))
print (6*(-2*7 - 5*8) - 1*(4*7 - 5*2) + 1*(4*8 - -2*2))
### output:
### -2.0
### [[ 6  1  1]
###  [ 4 -2  5]
###  [ 2  8  7]]
### -306.0
### -306

13.6 numpy.linalg.solve() and numpy.linalg.inv()

numpy.linalg.solve() 函数给出了矩阵形式的线性方程的解。
numpy.linalg.inv() 函数计算矩阵的乘法逆矩阵。

import numpy as np 
a = np.array([[1,1,1],[0,2,5],[2,5,-1]]); print ('数组 a:'); print (a)
ainv = np.linalg.inv(a); print ('a 的逆:'); print (ainv)
print ('矩阵 b:'); b = np.array([[6],[-4],[27]]); print (b)
print ('计算:A^(-1)B:'); x = np.linalg.solve(a,b);print (x)
# 这就是线性方向 x = 5, y = 3, z = -2 的解
### output:
### 数组 a:
### [[ 1  1  1]
###  [ 0  2  5]
###  [ 2  5 -1]]
### a 的逆:
### [[ 1.28571429 -0.28571429 -0.14285714]
###  [-0.47619048  0.14285714  0.23809524]
###  [ 0.19047619  0.14285714 -0.0952381 ]]
### 矩阵 b:
### [[ 6]
###  [-4]
###  [27]]
### 计算:A^(-1)B:
### [[ 5.]
###  [ 3.]
###  [-2.]]
###### 结果也可以由改公式获得:x = np.dot(ainv,b)

14 NumPy IO

14.1 numpy.save()

numpy.save() 函数将数组保存到以 .npy 为扩展名的文件中。

import numpy as np 
a = np.array([1,2,3,4,5]) 
# 保存到 outfile.npy 文件上
np.save('outfile.npy',a) 
# 保存到 outfile2.npy 文件上,如果文件路径末尾没有扩展名 .npy,该扩展名会被自动加上
np.save('outfile2',a)
### 用 load() 函数来读取数据
b = np.load('outfile.npy')  
print (b)
### output:
### [1 2 3 4 5]

14.2 numpy.savez()

numpy.savez() 函数将多个数组保存到以 npz 为扩展名的文件中。

import numpy as np 
a = np.array([[1,2,3],[4,5,6]])
b = np.arange(0, 1.0, 0.1)
c = np.sin(b)
# c 使用了关键字参数 sin_array
np.savez("runoob.npz", a, b, sin_array = c)
r = np.load("runoob.npz")  
print(r.files) # 查看各个数组名称
print(r["arr_0"]) # 数组 a
print(r["arr_1"]) # 数组 b
print(r["sin_array"]) # 数组 c
### output:
### ['sin_array', 'arr_0', 'arr_1']
### [[1 2 3]
###  [4 5 6]]
### [0.  0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]
### [0.         0.09983342 0.19866933 0.29552021 0.38941834 0.47942554
###  0.56464247 0.64421769 0.71735609 0.78332691]

14.3 numpy.savetxt() and numpy.loadtxt()

savetxt() 函数是以简单的文本文件格式存储数据,对应的使用 loadtxt() 函数来获取数据。

import numpy as np 
a=np.arange(0,10,0.5).reshape(4,-1)
np.savetxt("out.txt",a,fmt="%d",delimiter=",") # 改为保存为整数,以逗号分隔
b = np.loadtxt("out.txt",delimiter=",") # load 时也要指定为逗号分隔
print(b)
### output:
### [[0. 0. 1. 1. 2.]
###  [2. 3. 3. 4. 4.]
###  [5. 5. 6. 6. 7.]
###  [7. 8. 8. 9. 9.]]

  1. https://www.runoob.com/numpy/numpy-array-creation.html ↩︎

你可能感兴趣的:(Python,Study)