文章目录
- numpy数学函数
- numpy算术函数
- numpy 统计函数
- numpy排序, 条件刷选函数
- numpy字节交换
- 副本和视图(深拷贝和浅拷贝)
- 矩阵(Matrix)
- 线性代数
- numpy IO
- matplotlib
NumPy
numpy 是python语言的一个扩展程序库, 支持大量的维度数组与矩阵运算, 此外也针对数组提供大量的数学函数库.
numpy是一个运行速度非常快的数学库, 主要用于数组计算, 包含:
一个强大的N维数组对象ndarry
广播功能函数
整合C/C++/Fortran代码的工具
线性代数, 傅里叶变换, 随机数生成等功能
numpy应用
numpy与scipy(Scientific Python)和 Matplotlib(绘图库)一起使用, 这种组合广泛用于替代 MatLab,是一个强大的科学计算环境,有助于我们通过 Python 学习数据科学或者机器学习。
SciPy 是一个开源的 Python 算法库和数学工具包。
SciPy 包含的模块有最优化、线性代数、积分、插值、特殊函数、快速傅里叶变换、信号处理和图像处理、常微分方程求解和其他科学与工程中常用的计算。
Matplotlib 是 Python 编程语言及其数值数学扩展包 NumPy 的可视化操作界面。它为利用通用的图形用户界面工具包,如 Tkinter, wxPython, Qt 或 GTK+ 向应用程序嵌入式绘图提供了应用程序接口(API)。
numpy 安装
-
使用已经集成了这些模块的开发工具如Anaconda, Enthought Canopy, Python(x,y), WinPython, Pyzo
-
使用pip来安装
python -m pip install --user numpy scipy matplotlib ipython jupyter pandas sympy nose
–user 选项可以设置只安装在当前的用户下, 而不是写入到系统目录
linux下安装
ubuntu&debian
sudo apt-get install python-numpy python-scipy python-matplotlib ipython ipython-notebook python-pandas python-sympy python-nose
centos& Fedora
sudo dnf install numpy scipy python-matplotlib ipython python-pandas sympy python-nose atlas-devel
mac:
python -m pip install numpy scipy matplotlib
安装验证
>>> from nummpy import *
>>> eye(4)
array([[ 1., 0., 0., 0.],
[ 0., 1., 0., 0.],
[ 0., 0., 1., 0.],
[ 0., 0., 0., 1.]])
eye(4)生成对角矩阵
numpy Ndarray 对象
NumPy 最重要的一个特点是其 N 维数组对象 ndarray,它是一系列同类型数据的集合,以 0 下标为开始进行集合中元素的索引。
ndarray 对象是用于存放同类型元素的多维数组。
ndarray 中的每个元素在内存中都有相同存储大小的区域。
ndarray 内部由以下内容组成:
1.一个指向数据(内存或内存映射文件中的一块数据)的指针
2.数据类型或dtype, 描述在数组中的固定大小值的格子
3.一个表示数组形状(shape)的元组, 表示各维度大小的元组
4.一个跨度元组(stride), 其中的整数指的是为了前进到当前维度下一个元素需要"跨过"的字节数.
ndarray内部结构:
跨度可以是负数, 这样会使数组在内存中向后移动, 切片中obj[::-1]
或obj[:,::-1]
就是如此.
创建一个ndarray只需要调用Numpy的array函数即可:
numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
名称 | 描述 |
---|---|
object | 数组或嵌套的数列 |
dtype | 数组元素的数据类型, 可选 |
copy | 对象是否需要复制, 可选 |
order | 创建数组的样式, C为行方向, F为列方向, A为任意方向(默认) |
subok | 默认返回一个与基类类型一致的数组 |
ndmin | 指生成数的最小维度 |
实例
import numpy
a = numpy.array([1,2,3])
print (a)
输出:
[1 2 3]
实例2:
# 多于一个维度, 两个数组
import numpy
a = numpy.array([[1,2,3], [4,5]])
print (a)
[[1, 2, 3] [4, 5]]
[Finished in 0.1s]
实例3:
# 最小维度
import numpy
a = numpy.array([1,2,3,4,5],ndmin = 2)
print (a)
输出:
[[1 2 3 4 5]]
[Finished in 0.1s]
实例4:
# dtype 参数
import numpy
a = numpy.array([1,2,3,4,5], dtype = complex)
print (a)
输出:
[ 1.+0.j 2.+0.j 3.+0.j 4.+0.j 5.+0.j]
[Finished in 0.1s]
ndarray对象由计算机内存的连续一维部分组成, 并结合索引模式, 将每个元素映射到内存块中的一个位置. 内存块一行顺序(C样式)或列顺序(FORTRAN或Matlab风格, 即F样式)来保存元素
numpy数据类型
numpy支持的数据类型比python内置的类型要多很多, 基本上可以和C语言的数据类型对应上, 其中部分类型对应为Python内置的类型.
常用基本类型:
名称 | 描述 |
---|---|
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 位浮点数(实数部分和虚数部分) |
numpy的数值类型实际上是dtype对象的实例, 并对应唯一的字符, 包括np.bool_. np.int32, np.float32 , 等等
数据类型对象(dtype)
数据类型对象是用来描述与数组对应的内存区域如何使用, 这依赖如下几个方面:
- 数据类型(整数, 浮点数或者python对象)
- 数据的大小(列如, 整数使用多少个字节存储)
- 数据的字节顺序(小端法或大端法)
- 在结构化类型的情况下, 字段的名称, 每个字段的数据类型和每个字段所取的内存块的部分
- 如果数据 类型是子数组, 他的形状和数据类型
字节顺序是通过对数据类型预先设定"<“或”>"来决定的. "<"意味着小端法(最小值存储在最小的地址, 即低位组放在最前面). ">"意味着大端法(最重要的字节存储在最小的地址, 即高位组放在最前面).
dtype对象是使用以下语法构造的:
numpy.dtype(object, align, copy)
object
: 要转换为的数据类型对象
align:
如果为true, 填充字段使其类似C的结构体
copy:
复制dtype对象, 如果为false, 则是对内置数据类型对象的引用
实例
import numpy
# 使用标量类型
a = numpy.dtype(numpy.int32)
print (a)
输出:
int32
[Finished in 0.1s]
实例2:
# int8, int16, int32, int64 四种数据类型可以使用字符串 'i1', 'i2','i4','i8' 代替
import numpy
a = numpy.dtype('i4')
print (a)
输出:
int32
[Finished in 0.1s]
实例3:
import numpy
# 字节顺序标注
a = numpy.dtype('<i4')
print (a)
输出:
int32
结构化数据类型的使用, 类型字段和对应的实际类型将被创建.
实例4:
import numpy
a = numpy.dtype([('age', numpy.int8)])
print (a)
[('age', 'i1')]
[Finished in 0.1s]
实例5:
import numpy
# 数据类型应用到ndarray对象
dt = numpy.dtype([('age', numpy.int8)])
a = numpy.array([(10,),(20,),(30,)], dtype = dt)
print (a)
[(10,) (20,) (30,)]
[Finished in 0.1s]
实例6:
# 类型字段名可以用于存取实际的age列
import numpy
dt = numpy.dtype([('age', numpy.int8)])
a = numpy.array([(10,),(20,),(30,)], dtype = dt)
print (a['age'])
[10 20 30]
[Finished in 0.1s]
下面的示例定义一个结构化数据类型 student,包含字符串字段 name,整数字段 age,及浮点字段 marks,并将这个 dtype 应用到 ndarray 对象
实例7:
import numpy
student = numpy.dtype([('name','S20'),('age','i1'),('marks','f4')])
print (student)
[('name', 'S20'), ('age', 'i1'), ('marks', '<f4')]
[Finished in 0.1s]
实例8:
import numpy
student = numpy.dtype([('name','S20'),('age','i1'),('marks','f4')])
a = numpy.array([('abc', 21,50),('xyz', 18, 75)], dtype = student)
print (a)
[(b'abc', 21, 50.) (b'xyz', 18, 75.)]
[Finished in 0.1s]
dtype相当于提前定义的一张数据表里面各个字段的 名字 数据类型, numpy.array()按照提前定义的字段, 依次填入进去. 注意python2和3的区别.
每个内建类型都已一个唯一定义它的字符代码如下:
字符 | 对应类型 |
---|---|
b | 布尔型 |
i | (有符号) 整型 |
u | 无符号整型 integer |
f | 浮点型 |
c | 复数浮点型 |
m | timedelta(时间间隔) |
M | datetime(日期时间) |
O | (Python) 对象 |
S, a | (byte-)字符串 |
U | Unicode |
V | 原始数据 (void) |
numpy数组属性
NumPy 数组的维数称为秩(rank),秩就是轴的数量,即数组的维度,一维数组的秩为 1,二维数组的秩为 2,以此类推。
在 NumPy中,每一个线性的数组称为是一个轴(axis),也就是维度(dimensions)。比如说,二维数组相当于是两个一维数组,其中第一个一维数组中每个元素又是一个一维数组。所以一维数组就是 NumPy 中的轴(axis),第一个轴相当于是底层数组,第二个轴是底层数组里的数组。而轴的数量——秩,就是数组的维数。
很多时候可以声明 axis。axis=0,表示沿着第 0 轴进行操作,即对每一列进行操作;axis=1,表示沿着第1轴进行操作,即对每一行进行操作。
NumPy 的数组中比较重要 ndarray 对象属性有:
属性 | 说明 |
---|---|
ndarray.ndim | 秩,即轴的数量或维度的数量 |
ndarray.shape | 数组的维度,对于矩阵,n 行 m 列 |
ndarray.size | 数组元素的总个数,相当于 .shape 中 n*m 的值 |
ndarray.dtype | ndarray 对象的元素类型 |
ndarray.itemsize | ndarray 对象中每个元素的大小,以字节为单位 |
ndarray.flags | ndarray 对象的内存信息 |
ndarray.real | ndarray元素的实部 |
ndarray.imag | ndarray 元素的虚部 |
ndarray.data | 包含实际数组元素的缓冲区,由于一般通过数组的索引获取元素,所以通常不需要使用这个属性。 |
ndarray.ndim
返回数组的维数等于秩
import numpy
a = numpy.arange(24)
print (a.ndim) # a现只有一个维度
# 现在调整其大小
b = a.reshape(2,4,3) # b现在拥有3个维度
print (b.ndim)
1
3
ndarray.shape
ndarray.shape 表示数组的维度,返回一个元组,这个元组的长度就是维度的数目,即 ndim 属性(秩)。比如,一个二维数组,其维度表示"行数"和"列数"。
ndarray.shape 也可以用于调整数组大小。
实例:
import numpy
a = numpy.array([[1,2,3],[4,5,6]])
print (a.shape) # 二行三列
(2, 3)
[Finished in 0.1s]
调整大小:
import numpy
a = numpy.array([[1,2,3],[4,5,6]])
a.shape = (3,2) # 三行二列
print (a)
[[1 2]
[3 4]
[5 6]]
[Finished in 0.1s]
numpy也提供了reshape函数来调整数组大小.
import numpy
a = numpy.array([[1,2,3],[4,5,6]])
b = a.reshape(3,2)
print (b)
[[1 2]
[3 4]
[5 6]]
[Finished in 0.3s]
ndarray.itemsize
ndarray.itemsize 以字节的形式返回数组中每一个元素的大小。
例如,一个元素类型为 float64 的数组 itemsiz 属性值为 8(float64 占用 64 个 bits,每个字节长度为 8,所以 64/8,占用 8 个字节),又如,一个元素类型为 complex32 的数组 item 属性为 4(32/8)。
实例:
import numpy
# 数组的dtype为int8(一个字节)
a = numpy.array([1,99,2,3,4,5], dtype = numpy.int8)
print (a.itemsize)
# 数组的dtype现在为float64(8个字节)
b = numpy.array([1,2,3,4,5], dtype = numpy.float64)
print (b.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
a = numpy.array([1,2,33])
print (a.flags)
C_CONTIGUOUS : True
F_CONTIGUOUS : True
OWNDATA : True
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False
[Finished in 0.1s]
numpy创建数组
ndarray数组除了可以使用底层ndarray构造器来创建外, 也可以通过以下几种方式来创建.
numpy.empty
numpy.empty 方法用来创建一个指定形状(shape), 数据类型(dtype)且未初始化的数组:
numpy.empty(shape, dtype = float, order = 'C')
参数 | 描述 |
---|---|
shape | 数组形状 |
dtype | 数据类型,可选 |
order | 有"C"和"F"两个选项,分别代表,行优先和列优先,在计算机内存中的存储元素的顺序。 |
import numpy
a = numpy.empty([3,2], dtype = int)
print (a)
[[ 140605049899912 140605049899912]
[ 140605009638320 140605009626224]
[7205759936368964608 72483105062780931]]
[Finished in 0.1s]
数组元素为随机值, 因为他们还未初始化
numpy.zeros
创建指定大小的数组, 数组元素以0 来填充.
numpy.zeros(shape, dtype = float, order = 'C')
参数说明:
参数 | 描述 |
---|---|
shape | 数组形状 |
dtype | 数据类型,可选 |
order | ‘C’ 用于 C 的行数组,或者 ‘F’ 用于 FORTRAN 的列数组 |
import numpy
# 默认为浮点数
a = numpy.zeros(5)
print (a)
# 设置类型为整数
b = numpy.zeros((5,),dtype = numpy.int)
print (b)
# 自定义类型
c = numpy.zeros((2,2), dtype = [('x', 'i4'), ('y', 'i4')])
print (c)
[ 0. 0. 0. 0. 0.]
[0 0 0 0 0]
[[(0, 0) (0, 0)]
[(0, 0) (0, 0)]]
[Finished in 0.1s]
numpy.ones
创建指定形状的数组, 数组元素以1来填充:
numpy.ones(shape, dtype = None, order = 'C')
参数解释:
参数 | 描述 |
---|---|
shape | 数组形状 |
dtype | 数据类型,可选 |
order | ‘C’ 用于 C 的行数组,或者 ‘F’ 用于 FORTRAN 的列数组 |
实例:
import numpy
# 默认为浮点数
a = numpy.ones(5)
print (a)
# 自定义类型
b = numpy.ones([3,3], dtype = [('x', int),('y', float)])
print (b)
[ 1. 1. 1. 1. 1.]
[[(1, 1.) (1, 1.) (1, 1.)]
[(1, 1.) (1, 1.) (1, 1.)]
[(1, 1.) (1, 1.) (1, 1.)]]
[Finished in 0.1s]
从已有数组创建数组
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
x = [1,2,3]
a = numpy.asarray(x)
print (a)
[1 2 3]
[Finished in 0.1s]
元组转换为ndarray:
import numpy
x = (1,2,3)
a = numpy.asarray(x)
print (a)
[1 2 3]
元组列表转换为ndarray:
import numpy
x = [(1,2,3),(4,5)]
a = numpy.asarray(x)
print (a)
[(1, 2, 3) (4, 5)]
[Finished in 0.1s]
加上dtype参数:
import numpy
x = [1,2,3,4,5]
a = numpy.asarray(x, dtype = float)
print (a)
[ 1. 2. 3. 4. 5.]
[Finished in 0.1s]
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。 |
python3:
import numpy
s = b'hello word'
a = numpy.frombuffer(s, dtype = 'S1')
print (a)
[b'h' b'e' b'l' b'l' b'o' b' ' b'w' b'o' b'r' b'd']
[Finished in 0.1s]
python2:
import numpy
s = 'hello word'
a = numpy.frombuffer(s, dtype = 'S1')
print (a)
pig@deep:~/Desktop/note/python/numpy$ python test.py
['h' 'e' 'l' 'l' 'o' ' ' 'w' 'o' 'r' 'd']
numpy.fromiter
numpy.fromiter 方法从可迭代对象中建立ndarray 对象, 返回一维数组
numpy.fromiter(iterable, dtype, count = -1)
参数 | 描述 |
---|---|
iterable | 可迭代对象 |
dtype | 返回数组的数据类型 |
count | 读取的数据数量,默认为-1,读取所有数据 |
import numpy
# 使用range函数创建列表对象
list = range(5)
it = iter(list)
# 使用迭代器创建 ndarray
a = numpy.fromiter(it, dtype = float)
print (a)
[ 0. 1. 2. 3. 4.]
[Finished in 0.1s]
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
a = numpy.arange(5, dtype = float)
print (a)
[ 0. 1. 2. 3. 4.]
[Finished in 0.1s]
设置起始值, 终止值及步长:
import numpy
a = numpy.arange(10,20,2, dtype = float)
print (a)
[ 10. 12. 14. 16. 18.]
[Finished in 0.1s]
numpy.linspace
numpy.linspace
函数用于创建一个一维数组, 数组是一个等差数列构成的, 格式如下:
numpy.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
a = numpy.linspace(1,10,10, dtype = float)
print (a)
[ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]
[Finished in 0.1s]
设置元素为1的等差数列:
import numpy
a = numpy.linspace(1,1,10, dtype = float)
print (a)
[ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[Finished in 0.1s]
将endpoint设为false, 不包含终止值;
import numpy
a = numpy.linspace(10,20,5,endpoint = False, dtype = float)
print (a)
[ 10. 12. 14. 16. 18.]
[Finished in 0.1s]
如果将endpoint 设为true, 则会包含20.
以下实例设置间距:
import numpy
a = numpy.linspace(1,10,10,retstep = True)
print (a)
# 拓展列子
b = numpy.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.]]
[Finished in 0.1s]
numpy.logspace
numpy.logspace
函数用于创建一个等比数列格式如下:
numpy.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 的数据类型 |
import numpy
# 默认底数是10
a = numpy.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. ]
[Finished in 0.1s]
import numpy
# 底数是2
a = numpy.logspace(0, 9,10, base=2)
print (a)
[ 1. 2. 4. 8. 16. 32. 64. 128. 256. 512.]
[Finished in 0.1s]
numpy切片和索引
ndarray对象的内容可以通过索引或切片来访问和修改,与 Python 中 list 的切片操作一样。
ndarray 数组可以基于 0 - n 的下标进行索引,切片对象可以通过内置的 slice 函数,并设置 start, stop 及 step 参数进行,从原数组中切割出一个新数组。
>>> import numpy
>>> a = numpy.arange(10)
>>> s = slice(2,7,2) # 从索引2 开始索引到7停止, 间隔为2
>>> print (a[s])
[2 4 6]
通过arange()函数创建ndarray对象, 然后, 分别设置起始, 终止和步长的参数为2, 7 和2.
也可以通过冒号分割切片参数start:stop:step
来进行切片操作:
>>> import numpy
>>> a = numpy.arange(10)
>>> b = a[2:7:2]
>>> print (b)
[2 4 6]
>>>
索引和list中的索引差不多 单个参数[2] , [2:]索引开始后面的所有项都将提取,如果[2:7] 则提取两个索引之间的项(不包括停止索引)
多维数组同样适用上述索引提取方法:
>>> import numpy
>>> a = numpy.array([[1,2,3],[4,5,6],[7,8,9]])
>>> print (a)
[[1 2 3]
[4 5 6]
[7 8 9]]
>>> print (a[1:])
[[4 5 6]
[7 8 9]]
>>>
切片还可以包括省略号...
来使选择元组的长度与数组的维度相同, 如果在行位置使用省略号, 他将返回包含行中元素的ndarray
>>> import numpy
>>> a = numpy.array([[1,2,3],[4,5,6],[7,8,9]])
>>> print (a[...,1]) # 第二列元素
[2 5 8]
>>> print (a[1,...]) # 第二行元素
[4 5 6]
>>> print (a[...,1:]) # 第二例及剩下的所有元素
[[2 3]
[5 6]
[8 9]]
>>>
numpy 高级索引
NumPy 比一般的 Python 序列提供更多的索引方式。除了之前看到的用整数和切片的索引外,数组可以由整数数组索引、布尔索引及花式索引。
整数数组索引
以下实例获取数组中(0,0),(1,1)和(2,0)位置处的元素。
import numpy
x = numpy.array([[1,2],[3,4],[5,6]])
y = x[[0,1,2], [0,1,0]]
print (y)
[1 4 5]
[Finished in 0.1s]
区别:
import numpy
x = numpy.array([[1,2],[3,4],[5,6]])
y = x[[0,1], [0,1]]
print (y)
print (x)
[1 4]
[[1 2]
[3 4]
[5 6]]
[Finished in 0.1s]
获取4x3数组中的四个角元素, 行索引为[0,0]和[3,3] 而列索引为[0,2]和[0,2]
import numpy
x = numpy.array([[0,1,2],[3,4,5],[6,7,8],[9,10,11]])
print ('数组:')
print (x)
print ('\n')
rows = numpy.array([[0,0],[3,3]])
cols = numpy.array([[0,2],[0,2]])
y = x[rows, cols]
print ('角上的四个元素:')
print (y)
坐标为00 02 30 32
数组:
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]
角上的四个元素:
[[ 0 2]
[ 9 11]]
[Finished in 0.1s]
返回结果是包含每个角元素的ndarray对象
可以借助切片:
或...
与索引数组组合
import numpy
a = numpy.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 (a)
print (b)
print (c)
print (d)
[[1 2 3]
[4 5 6]
[7 8 9]]
[[5 6]
[8 9]]
[[5 6]
[8 9]]
[[2 3]
[5 6]
[8 9]]
[Finished in 0.1s]
要获取元素 的行索引集合, 列索引集合来获取元素, 如果是获取某个区域的元素, 则使用:
布尔索引
我们可以通过一个布尔数组来索引目标数组。
布尔索引通过布尔运算(如:比较运算符)来获取符合指定条件的元素的数组。
以下实例获取大于 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])
我们的数组是:
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]
大于 5 的元素是:
[ 6 7 8 9 10 11]
[Finished in 0.3s]
以下使用~
(取补运算符) 来过滤NaN
import numpy
a = numpy.array([numpy.nan, 1, 2, numpy.nan, 3, 4, 5])
print (a[~numpy.isnan(a)])
[ 1. 2. 3. 4. 5.]
[Finished in 0.1s]
从数组中过滤掉非复数元素:
import numpy
a = numpy.array([1, 2+6j,5,3.5])
print (a[numpy.iscomplex(a)])
[ 2.+6.j]
[Finished in 0.1s]
花式索引
花式索引指的是利用整数数组进行索引。
花式索引根据索引数组的值作为目标数组的某个轴的下标来取值。对于使用一维整型数组作为索引,如果目标是一维数组,那么索引的结果就是对应位置的元素;如果目标是二维数组,那么就是对应下标的行。
花式索引跟切片不一样,它总是将数据复制到新数组中。
-
传入顺序索引数组
import numpy a = numpy.arange(32) x = a.reshape((8,4)) print (a) print (x) print (x[[4,2,1,7]]) [ 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] [[ 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]] [[16 17 18 19] [ 8 9 10 11] [ 4 5 6 7] [28 29 30 31]] [Finished in 0.1s]
-
传入倒叙索引数组
import numpy
a = numpy.arange(32)
x = a.reshape((8,4))
print (a)
print (x)
print (x[[-4,-2,-1,-7]])
[ 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]
[[ 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]]
[[16 17 18 19]
[24 25 26 27]
[28 29 30 31]
[ 4 5 6 7]]
[Finished in 0.1s]
- 传入多个索引数组(要使用np.ix_)
import numpy
a = numpy.arange(32)
x = a.reshape((8,4))
print (x)
print (x[numpy.ix_([1,5,7,2],[0,3,1,2])])
[[ 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 7 5 6]
[20 23 21 22]
[28 31 29 30]
[ 8 11 9 10]]
[Finished in 0.1s]
行索引配合列索引
numpy广播(broadcast)
广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式, 对数组的算术运算通常在相应的元素上进行。
如果两个数组 a 和 b 形状相同,即满足 a.shape == b.shape,那么 a*b 的结果就是 a 与 b 数组对应位相乘。这要求维数相同,且各维度的长度相同。
[1,2,3,4] * [10,20,30,40]
import numpy
a = numpy.array([1,2,3,4])
b = numpy.array([10,20,30,40])
c = a * b
print (c)
[ 10 40 90 160]
[Finished in 0.1s]
当运算中的两个数组形状不同时, numpy将自动触发广播机制.:
import numpy
a = numpy.array([[0,0,0],
[10,10,10],
[20,20,20],
[30,30,30]])
b = numpy.array([1,2,3])
print (a + b)
[[ 1 2 3]
[11 12 13]
[21 22 23]
[31 32 33]]
[Finished in 0.1s]
广播的规则:
- 让所有输入数组都向其中形状最长的数组看齐,形状中不足的部分都通过在前面加 1 补齐。
- 输出数组的形状是输入数组形状的各个维度上的最大值。
- 如果输入数组的某个维度和输出数组的对应维度的长度相同或者其长度为 1 时,这个数组能够用来计算,否则出错。
- 当输入数组的某个维度的长度为 1 时,沿着此维度运算时都用此维度上的第一组值。
**简单理解:**对两个数组,分别比较他们的每一个维度(若其中一个数组没有当前维度则忽略),满足:
- 数组拥有相同形状。
- 当前维度的值相等。
- 当前维度的值有一个是 1。
若条件不满足,抛出 “ValueError: frames are not aligned” 异常。
tile()
函数就是将原矩阵横向, 纵向的复制.
tile(mat, (1,4))
复制为原来的四倍
numpy 迭代数组
NumPy 迭代器对象 numpy.nditer 提供了一种灵活访问一个或者多个数组元素的方式。
迭代器最基本的任务的可以完成对数组元素的访问。
接下来我们使用 arange() 函数创建一个 2X3 数组,并使用 nditer 对它进行迭代。
import numpy as np
a = np.arange(6).reshape(2,3)
print ('原数组:')
print (a)
print ('\n')
for x in np.nditer(a):
print (x, end=', ')
print ('\n')
原数组:
[[0 1 2]
[3 4 5]]
0, 1, 2, 3, 4, 5,
[Finished in 0.1s]
以上实例不是使用标准 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):
print (x, end=', ')
print ('\n')
for x in np.nditer(a.T.copy(order='C')):
print (x, end=', ')
print ('\n')
0, 1, 2, 3, 4, 5,
0, 3, 1, 4, 2, 5,
[Finished in 0.1s]
从上述例子可以看出,a 和 a.T 的遍历顺序是一样的,也就是他们在内存中的存储顺序也是一样的,但是 a.T.copy(order = ‘C’) 的遍历结果是不同的,那是因为它和前两种的存储方式是不一样的,默认是按行访问。
控制便来顺序
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=', ')
原数组:
[[ 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, [Finished in 0.1s]
b=a.T
表示数组的转置, 默认情况下nditer是以行来读取的, 当然也可以直接以列来读取, 使用nditer指定order以什么方式读取如下:
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print (str('原').center(15,'*'))
print (a)
print ('\n')
print (str('C').center(15,'*'))
for x in np.nditer(a, order = 'C'):
print (x, end = ', ')
print ('\n')
print ('F'.center(15, '*'))
for x in np.nditer(a, order = 'F'):
print (x, end = ', ')
*******原*******
[[ 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, [Finished in 0.1s]
修改数组中元素的值
nditer 对象有另一个可选参数op_flags 默认情况下, nditer将视待迭代遍历的数组为只读对象(read-only), 为了在遍历数组的同时, 实现对数组元素值得修改, 必须指定read-write 或者 write-only 的模式.
import numpy
a = numpy.arange(0,60,5)
a = a.reshape(3,4)
print ('原始数组'.center(15,'*'))
print (a)
print ('\n')
for x in numpy.nditer(a, op_flags=['readwrite']):
x[...]=2*x
print ('修改后'.center(15,'*'))
print (a)
******原始数组*****
[[ 0 5 10 15]
[20 25 30 35]
[40 45 50 55]]
******修改后******
[[ 0 10 20 30]
[ 40 50 60 70]
[ 80 90 100 110]]
[Finished in 0.1s]
使用外部循环:
nditer 类的构造器拥有flags参数, 他可以接受下列值:
参数 | 描述 |
---|---|
c_index | 可以跟踪 C 顺序的索引 |
f_index | 可以跟踪 Fortran 顺序的索引 |
multi-index | 每次迭代可以跟踪一种索引类型 |
external_loop | 给出的值是具有多个值的一维数组,而不是零维数组 |
import numpy
a = numpy.arange(0,60,5)
a = a.reshape(3,4)
print ('原始数组'.center(20,'*'))
print (a)
print ('\n')
print ('修改后的数组:'.center(20,'*'))
for x in numpy.nditer(a, flags = ['external_loop'], order = 'F'):
print (x, end=", ")
********原始数组********
[[ 0 5 10 15]
[20 25 30 35]
[40 45 50 55]]
******修改后的数组:*******
[ 0 20 40], [ 5 25 45], [10 30 50], [15 35 55], [Finished in 0.1s]
广播迭代
如果两个数组是可广播的, nditer组合对象能够同时迭代他们, 假设数组a的维度为3x4, 数组b的维度为1x4 则使用以下迭代器(数组b被广播到a的大小)
import numpy
a = numpy.arange(0,60,5)
a = a.reshape(3,4)
print ('第一个数组'.center(20, "*"))
print (a)
print ('\n')
print ('第二个数组'.center(20, "*"))
b = numpy.array([1,2,3,4],dtype = int)
print (b)
print ('\n')
print ('修改之后的数组'.center(20, "*"))
for x,y in numpy.nditer([a,b]):
print ('%d:%d' % (x, y), end=', ')
*******第一个数组********
[[ 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, [Finished in 0.1s]
数组操作
处理数组大概分为以下几类:
- 修改数组形状
- 翻转数组
- 修改数组 维度
- 连接数组
- 分割数组
- 数组元素的添加与删除
修改数组形状
函数 | 描述 |
---|---|
reshape | 不改变数据的条件下修改形状 |
flat | 数组元素迭代器 |
flatten | 返回一份数组拷贝,对拷贝所做的修改不会影响原始数组 |
ravel | 返回展开数组 |
numpy.reshape
numpy.reshape 函数可以在不改变数据的条件下修改形状,格式如下: numpy.reshape(arr, newshape, order=‘C’)
arr
:要修改形状的数组newshape
:整数或者整数数组,新的形状应当兼容原有形状- order:‘C’ – 按行,‘F’ – 按列,‘A’ – 原顺序,‘k’ – 元素在内存中的出现顺序。
import numpy as np
a = np.arange(8)
print ('原始数组:')
print (a)
print ('\n')
b = a.reshape(4,2)
print ('修改后的数组:')
print (b)
输出结果如下:
原始数组:
[0 1 2 3 4 5 6 7]
修改后的数组:
[[0 1]
[2 3]
[4 5]
[6 7]]
numpy.ndarray.flat
numpy.ndarray.flat 是一个数组元素迭代器, 实例:
import numpy
a = numpy.arange(9).reshape(3,3)
print ('原数组'.center(20,'*'))
for row in a:
print (row)
# 对数组中每个元素都进行处理, 可以使用flat属性, 该属性是一个数组元素迭代器.
print ('迭代后的数组'.center(20, '*'))
for element in a.flat:
print (element)
********原数组*********
[0 1 2]
[3 4 5]
[6 7 8]
*******迭代后的数组*******
0
1
2
3
4
5
6
7
8
[Finished in 0.3s]
numpy.ndarray.flatten
numpy.ndarray.flatten 返回一份数组拷贝, 对拷贝所做的修改不会影响原始数组, 格式:
ndarray.flatten(order='C')
order
‘C’–按行, ‘F’-- 按列, ‘A’ – 按原顺序, ‘K’ – 元素在内存中的出现顺序.
import numpy
a = numpy.arange(8).reshape(2,4)
print('原'.center(20, '*'))
print (a)
print ('\n')
print ('展开数组:'.center(20, '*'))
print (a.flatten())
print ('\n')
print ('F顺序展开的数组')
print (a.flatten(order='F'))
*********原**********
[[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]
[Finished in 0.1s]
numpy.ravel
numpy.ravel ()展平的数组元素, 顺序通常是"C风格", 返回数组视图(view, 有点类似C/C++引用reference的意味), 修改会影响原始数组,
numpy.ravel(a, order = 'C')
实例:
import numpy
a = numpy.arange(8).reshape(2,4)
print('原'.center(20, '*'))
print (a)
print ('\n')
print ('调用ravel函数之后'.center(20, '*'))
print (a.ravel())
print ('\n')
print ('F顺序调用ravel函数的数组')
print (a.ravel(order = 'F'))
*********原**********
[[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]
[Finished in 0.1s]
翻转数组
函数 | 描述 |
---|---|
transpose | 对换数组的维度 |
ndarray.T | 和 self.transpose() 相同 |
rollaxis | 向后滚动指定的轴 |
swapaxes | 对换数组的两个轴 |
numpy.transpose
numpy.transpose
函数用于对换数组的维度
numpy.transpose(arr, axes)
arr
要操作的数组
axes
整数列表, 对应维度, 通常所有维度都会对换
import numpy
a = numpy.arange(12).reshape(3,4)
print('原'.center(20, '*'))
print (a)
print ('\n')
print ('对换数组'.center(20, '*'))
print (numpy.transpose(a))
print ('\n')
*********原**********
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
********对换数组********
[[ 0 4 8]
[ 1 5 9]
[ 2 6 10]
[ 3 7 11]]
[Finished in 0.2s]
numpy.ndarray.T 类似numpy.transpose:
import numpy
a = numpy.arange(12).reshape(3,4)
print('原'.center(20, '*'))
print (a)
print ('\n')
print ('转置数组'.center(20, '*'))
print (a.T)
print ('\n')
*********原**********
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
********转置数组********
[[ 0 4 8]
[ 1 5 9]
[ 2 6 10]
[ 3 7 11]]
[Finished in 0.1s]
numpy.rollaxis
numpy.rollaxis
函数向后滚动特定的轴到一个特定位置, 格式如下:
numpy.rollaxis(arr, axis, start)
arr
数组
axis
向后滚动的轴, 其他轴的相对位置不会改变
start
默认为0, 表示完整的滚动, 回滚到特定的位置
import numpy
a = numpy.arange(8).reshape(2,2,2)
print('原'.center(20, '*'))
print (a)
print ('\n')
# 将轴2滚动到轴0(宽度到深度)
print ('调用rollaxis函数'.center(20, '*'))
print (numpy.rollaxis(a,2))
# 将轴0 滚动到轴1位置, (宽度到高度)
print ('\n')
print ('调用rollaxis函数')
print (numpy.rollaxis(a,2,1))
*********原**********
[[[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]]]
[Finished in 0.1s]
numpy.swapaxes
numpy.swapaxes
函数用于交换数组的两个轴, 格式如下:
numpy.swapaxes(arr, sxis1, axis2)
arr
数组
axis1
对应第一个轴的整数
axis2
对应第二个轴的整数
import numpy
a = numpy.arange(8).reshape(2,2,2)
print('原'.center(20, '*'))
print (a)
print ('\n')
# 现在交换轴0(深度方向)到轴2(宽度方向)
print ('调用swapaxes函数后的数组'.center(20, '*'))
print (numpy.swapaxes(a, 2, 0))
*********原**********
[[[0 1]
[2 3]]
[[4 5]
[6 7]]]
**调用swapaxes函数后的数组**
[[[0 4]
[2 6]]
[[1 5]
[3 7]]]
[Finished in 0.1s]
修改数组维度
维度 | 描述 |
---|---|
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 属性,基于自身组件的迭代器元组
print (b)
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))
print ('\n')
# 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)
print ('\n')
c.flat = [u + v for (u,v) in b]
print ('调用 flat 函数:')
print (c)
print ('\n')
# 获得了和 NumPy 内建的广播支持相同的结果
print ('x 与 y 的和:')
print (x + y)
<numpy.broadcast object at 0x55c6b266fdb0>
对 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]]
[Finished in 0.1s]
numpy.broadcast_to
numpy.broadcast_to
函数将数组广播到新形状, 他在原始数组上返回只读视图, 它通常不连续, 如果新形状不符合numpy的广播规则, 该函数可能会抛出ValueError
numpy.broadcast_to(array, shape, subok)
import numpy
a = numpy.arange(4).reshape(1,4)
print ('原数组:')
print (a)
print ('\n')
print ('调用broadcast_to函数之后')
print (numpy.broadcast_to(a,(2,4)))
原数组:
[[0 1 2 3]]
调用broadcast_to函数之后
[[0 1 2 3]
[0 1 2 3]]
[Finished in 0.1s]
numpy.expand_dims
numpy.expand_dims
函数通过指定位置插入新的轴来扩展数组形状, 函数格式:
numpy.expand_dims(arr, axis)
arr
输入的数组
axis
新轴插入的位置, 0 表示行, 1 表示列
import numpy
x = numpy.array(([1,2],[3,4]))
print ('数组x')
print (x)
print ('\n')
y = numpy.expand_dims(x, axis = 0)
print ('数组y')
print (y)
print ('\n')
print ('数组x和y的形状')
print (x.shape, y.shape)
print ('\n')
# 在轴1 位置插入轴
y = numpy.expand_dims(x, axis = 1)
print ('在位置1 插入轴之后的数组')
print (y)
print ('\n')
print ('x.ndim y.ndim')
print (x.ndim, y.ndim)
print ('\n')
print ('x.shape, y.shape')
print (x.shape, y.shape)
数组x
[[1 2]
[3 4]]
数组y
[[[1 2]
[3 4]]]
数组x和y的形状
(2, 2) (1, 2, 2)
在位置1 插入轴之后的数组
[[[1 2]]
[[3 4]]]
x.ndim y.ndim
2 3
x.shape, y.shape
(2, 2) (2, 1, 2)
[Finished in 0.1s]
numpy.squeeze
numpy.squeeze
从给定数组的形状中删除一维的条目,
numpy.squeeze(arr, axis)
arr
输入数组
axis
整数或整数元组, 用于选择形状中的一维条目的子集
import numpy
x = numpy.arange(9).reshape(1,3,3)
print ('数组x')
print (x)
print ('\n')
y = numpy.squeeze(x)
print ('数组y')
print (y)
print ('\n')
print ('x.shape, y.shape')
print (x.shape, y.shape)
数组x
[[[0 1 2]
[3 4 5]
[6 7 8]]]
数组y
[[0 1 2]
[3 4 5]
[6 7 8]]
x.shape, y.shape
(1, 3, 3) (3, 3)
[Finished in 0.1s]
连接数组
函数 | 描述 |
---|---|
concatenate | 连接沿现有轴的数组序列 |
stack | 沿着新的轴加入一系列数组。 |
hstack | 水平堆叠序列中的数组(列方向) |
vstack | 竖直堆叠序列中的数组(行方向) |
concatenate
用于沿着指定轴连接相同形状的两个或多个数组
numpy.concatenate((a1,a2, ...),axis)
a1,a2,a3,...
相同类型的数组
axis
沿着它连接数组的轴, 默认为0
import numpy
a = numpy.array([[1,2],[3,4]])
print ('第一个数组')
print (a)
print ('\n')
b = numpy.array([[5,6],[7,8]])
print ('第二个数组')
print (b)
print ('\n')
# 两个数组的维度相同
print ('沿轴0连接两个数组:')
print (numpy.concatenate((a,b)))
print ('\n')
print ('沿着轴1连接两个数组')
print (numpy.concatenate((a,b),axis = 1))
第一个数组
[[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]]
[Finished in 0.1s]
numpy.stack
用于沿新轴连接数组序列
numpy.stack(arrays, axis)
arrays
相同形状的数组序列
axis
返回数组中的轴, 输入数组沿着它来堆叠
import numpy
a = numpy.array([[1,2],[3,4]])
print ('第一个数组')
print (a)
print ('\n')
b = numpy.array([[5,6],[7,8]])
print ('第二个数组')
print (b)
print ('\n')
print ('沿着0堆叠两个数组')
print (numpy.stack((a,b),0))
print ('\n')
print ('沿着列堆叠两个数组')
print (numpy.stack((a,b),1))
第一个数组
[[1 2]
[3 4]]
第二个数组
[[5 6]
[7 8]]
沿着0堆叠两个数组
[[[1 2]
[3 4]]
[[5 6]
[7 8]]]
沿着列堆叠两个数组
[[[1 2]
[5 6]]
[[3 4]
[7 8]]]
[Finished in 0.1s]
numpy.hstack
是numpy.stack的变体, 通过水平堆叠来生成数组
import numpy
a = numpy.array([[1,2],[3,4]])
print ('第一个数组')
print (a)
print ('\n')
b = numpy.array([[5,6],[7,8]])
print ('第二个数组')
print (b)
print ('\n')
print ('水平堆叠')
c = numpy.hstack((a,b))
print (c)
第一个数组
[[1 2]
[3 4]]
第二个数组
[[5 6]
[7 8]]
水平堆叠
[[1 2 5 6]
[3 4 7 8]]
[Finished in 0.1s]
numpy.vstack
通过垂直堆叠来生成数组
import numpy
a = numpy.array([[1,2],[3,4]])
print ('第一个数组')
print (a)
print ('\n')
b = numpy.array([[5,6],[7,8]])
print ('第二个数组')
print (b)
print ('\n')
print ('垂直堆叠')
print (numpy.vstack((a,b)))
第一个数组
[[1 2]
[3 4]]
第二个数组
[[5 6]
[7 8]]
垂直堆叠
[[1 2]
[3 4]
[5 6]
[7 8]]
[Finished in 0.1s]
分割数组
函数 | 数组及操作 |
---|---|
split | 将一个数组分割为多个子数组 |
hsplit | 将一个数组水平分割为多个子数组(按列) |
vsplit | 将一个数组垂直分割为多个子数组(按行) |
numpy.split
沿特定的轴将数组分割为子数组
numpy.split(ary, indices_or_sections, axis)
ary
被分割的数组
indices_or_se_ctinos
如果是一个整数就用该数平均切分,如果是一个数组,为沿轴切分的位置(左开右闭)
沿哪个维度切割
0,1
import numpy
a = numpy.arange(9)
print ('第一个数组')
print (a)
print ('\n')
print ('将数组分为三个大小相等的子数组')
b = numpy.split(a, 3)
print (b)
print ('\n')
print ('将数组在一维数组中表明的位置分割')
b = numpy.split(a,[4,7])
print (b)
第一个数组
[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])]
[Finished in 0.1s]
numpy.hsplit
用于水平分割数组, 通过指定要返回的相同形状的数组数量来拆分原数组
import numpy
harr = numpy.floor(10 * numpy.random.random((2,6)))
print ('原数组')
print (harr)
print ('拆分后')
print (numpy.hsplit(harr,3))
原数组
[[ 6. 3. 8. 0. 4. 8.]
[ 6. 6. 7. 0. 3. 1.]]
拆分后
[array([[ 6., 3.],
[ 6., 6.]]), array([[ 8., 0.],
[ 7., 0.]]), array([[ 4., 8.],
[ 3., 1.]])]
[Finished in 0.3s]
numpy.vsplit
沿垂直轴分割, 分割方式和hsplit相同
import numpy
a = numpy.arange(16).reshape(4,4)
print ('第一个数组:')
print (a)
print ('\n')
print ('竖直分割')
b = numpy.vsplit(a,2)
print (b)
第一个数组:
[[ 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]])]
[Finished in 0.1s]
数组元素的添加与删除
函数 | 元素及描述 |
---|---|
resize | 返回指定形状的新数组 |
append | 将值添加到数组末尾 |
insert | 沿指定轴将值插入到指定下标之前 |
delete | 删掉某个轴的子数组,并返回删除后的新数组 |
unique | 查找数组内的唯一元素 |
numpy.resize
返回指定大小的新数组, 如果新数组大小大于原始大小, 则包含原数组中的元素副本
numpy.resize(arr, shape)
arr
要修改大小的数组
shape
返回数组的新形状
import numpy
a = numpy.array([[1,2,3],[4,5,6]])
print ('第一个数组')
print (a)
print ('\n')
print ('第一个数组形状')
print (a.shape)
print ('\n')
b = numpy.resize(a,(3,2))
print ('第二个数组')
print (b)
print ('第二个数组形状')
print (b.shape)
print ('\n')
# 注意a的第一行b中重复出现, 因为尺寸变大了
print ('修改后的第二个数组大小')
print (numpy.resize(a,(3,3)))
第一个数组
[[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]]
[Finished in 0.1s]
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时,数组是加在右边(行数要相同)。
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
print ('第一个数组')
print (a)
print ('\n')
print ('向数组添加元素')
print (np.append(a, [7,8,9]))
print ('\n')
print ('沿轴0添加元素')
print (np.append(a, [[7,8,9]], axis = 0))
print ('\n')
print ('沿轴1添加元素')
print (np.append(a, [[5,5,5],[7,8,9]], axis = 1))
第一个数组
[[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]]
[Finished in 0.1s]
numpy.insert
在给定索引之前, 沿给定轴在输入数组中插入值, 如果值的类型转换为要插入, 则它与输入数组不同, 插入没有原地的, 函数会返回一个新数组, 此外未提供轴, 则输入数组被展开.
numpy.insert(arr, obj, values, axis)
arr
输入数组
obj
在其 之前插入值的索引
values
要插入的值
axis
沿着它插入的轴, 如果未提供, 则输入数组会被展开
import numpy as np
a = np.array([[1,2], [3,4], [5,6]])
print ('第一个数组')
print (a)
print ('\n')
print ('未传递axis参数, 在插入之前输入数组会被展开')
print (np.insert(a,3,[11,22]))
print ('\n')
print ('传递axis参数, 会广播值数组来配输入数组')
print ('沿轴0广播')
print (np.insert(a, 1, [11], axis = 0))
print ('\n')
print ('沿轴1广播')
print (np.insert(a,1,11,axis = 1))
第一个数组
[[1 2]
[3 4]
[5 6]]
未传递axis参数, 在插入之前输入数组会被展开
[ 1 2 3 11 22 4 5 6]
传递axis参数, 会广播值数组来配输入数组
沿轴0广播
[[ 1 2]
[11 11]
[ 3 4]
[ 5 6]]
沿轴1广播
[[ 1 11 2]
[ 3 11 4]
[ 5 11 6]]
numpy.delete
返回从输入数组中删除指定子数组的新数组, 与insert函数一样, 如果未提供轴参数, 输入数组将展开
numpy.delete(arr, obj, axis)
arr
输入数组
obj
可以被切片, 整数或者整数数组, 表明要从输入数组删除的子数组
axis
沿着它删除给定子数组的轴, 如果未提供, 则输入数组会被展开
import numpy as np
a = np.arange(12).reshape(3,4)
print (a)
print ('\n')
print ('未传递axis参数, 在插入之前输入数组会被展开')
print (np.delete(a,5))
print ('删除第二列')
print (np.delete(a,1,axis = 1))
print ('\n')
print ('包含从数组中删除的替代值的切片')
a = np.array([1,2,3,4,5,6,7,8,9,10])
print (np.delete(a, np.s_[::2]))
[[ 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]
numpy.unique
用于去除数组中的重复元素
numpy.unique(arr, return_index, return_inverse, return_counts)
arr
输入数组, 如果不是一维数组则会展开
return_index
如果为true, 返回新列表元素在旧列表中的位置(下表), 并以列表形式存储
return_inverse
如果为true, 返回旧列表元素在新列表中的位置(下标), 并以列表形式存储
return_counts
如果为true, 返回去重数组中的元素在原数组中出现次数
import numpy as np
a = np.array([5,2,6,2,7,5,6,8,2,9])
print ('第一个数组')
print (a)
print ('\n')
print ('第一个数组的去重值')
u = np.unique(a)
print (u)
print ('\n')
print ('去重数组的索引数组')
u, indices = np.unique(a, return_index = True)
print (indices)
print ('\n')
print ('我们可以看到每个和原数组下表对应的数值')
print (a)
print ('\n')
print ('去重数组的下标')
u, indices = np.unique(a, return_inverse = True)
print (u)
print ('\n')
print ('下标为')
print (indices)
print ('\n')
print ('使用下标重构原数组')
print (u[indices])
print ('\n')
print ('返回去重元素的重复数量')
u, indices = np.unique(a, return_counts = True)
print (u)
print (indices)
第一个数组
[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]
numpy 位运算
NumPy “bitwise_” 开头的函数是位运算函数。
NumPy 位运算包括以下几个函数:
函数 | 描述 |
---|---|
bitwise_and | 对数组元素执行位与操作 |
bitwise_or | 对数组元素执行位或操作 |
invert | 按位取反 |
left_shift | 向左移动二进制表示的位 |
right_shift | 向右移动二进制表示的位 |
**注:**也可以使用 “&”、 “~”、 “|” 和 “^” 等操作符进行计算。
import numpy as np
print ('13和17二进制形式')
a,b = 13, 17
print (bin(a), bin(b))
print ('\n')
print ('13和17的位与')
print (np.bitwise_and(13,17))
13和17二进制形式
0b1101 0b10001
13和17的位与
1
以上实例可以用下表来说明:
1 | 1 | 0 | 1 | ||
---|---|---|---|---|---|
AND | |||||
1 | 0 | 0 | 0 | 1 | |
运算结果 | 0 | 0 | 0 | 0 | 1 |
位与操作运算规律如下:
A | B | AND |
---|---|---|
1 | 1 | 1 |
1 | 0 | 0 |
0 | 1 | 0 |
0 | 0 | 0 |
bitwise_or
对数组中整数的二进制形式执行位或运算
import numpy as np
a, b = 13, 17
print ('13和17的二进制形式')
print (bin(a), bin(b))
print ('13和17的位或')
print (np.bitwise_or(13,17))
13和17的二进制形式
0b1101 0b10001
13和17的位或
29
以上实例可以用下表来说明:
1 | 1 | 0 | 1 | ||
---|---|---|---|---|---|
OR | |||||
1 | 0 | 0 | 0 | 1 | |
运算结果 | 1 | 1 | 1 | 0 | 1 |
位或操作运算规律如下:
A | B | OR |
---|---|---|
1 | 1 | 1 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
invert
函数对数组中整数进行取反运算, 0变为1, 1变为0
对于有符号的整数, 取该二进制的补码然后+1 二进制数, 最高位为0表示整数, 最高位为1 表示负数
看看 ~1 的计算步骤:
-
将1(这里叫:原码)转二进制 = 00000001
-
按位取反 = 11111110
-
发现符号位(即最高位)为1(表示负数),将除符号位之外的其他数字取反 = 10000001
-
末位加1取其补码 = 10000010
-
转换回十进制 = -2
-
表达式 二进制值(2 的补数) 十进制值 5 00000000 00000000 00000000 0000010 5 ~5 11111111 11111111 11111111 11111010 -6
import numpy as np
print ('13的位反转,其中ndarra的dtype是uint8')
print (np.invert(np.array([13], dtype = np.uint8)))
print ('\n')
# 比较13和242的二进制数表示, 我们发现了位的反转
print ('13的二进制表示:')
print (np.binary_repr(13, width = 8))
print ('\n')
print ('242的二进制表示')
print (np.binary_repr(242, width = 8))
13的位反转,其中ndarra的dtype是uint8
[242]
13的二进制表示:
00001101
242的二进制表示
11110010
left_shift
将数组元素的二进制形式向左移动到指定位置, 右侧附加相等数量的0
import numpy as np
print ('将10向左移动两位')
print (np.left_shift(10,2))
print ('\n')
print ('10的二进制表示')
print (np.binary_repr(10, width = 8))
print ('40的二进制表示')
print (np.binary_repr(40, width = 8))
# '00001010'中的两位移动到左边, 并在右边添加了两个0
将10向左移动两位
40
10的二进制表示
00001010
40的二进制表示
00101000
right_shift
函数将数组元素的二进制形式向右移动到指定的位置, 左侧附加相等数量的0
import numpy as np
print ('将40右移两位')
print (np.right_shift(40,2))
print ('\n')
print ('40的二进制表示')
print (np.binary_repr(40, width = 8))
print ('\n')
print ('10的二进制表示')
print (np.binary_repr(10, width = 8))
# '00001010'中的两位移动到了右边, 并在左边添加了两个0
将40右移两位
10
40的二进制表示
00101000
10的二进制表示
00001010
numpy字符串函数
以下函数用于对 dtype 为 numpy.string_ 或 numpy.unicode_ 的数组执行向量化字符串操作。 它们基于 Python 内置库中的标准字符串函数。
这些函数在字符数组类(numpy.char)中定义。
函数 | 描述 |
---|---|
add() | 对两个数组的逐个字符串元素进行连接 |
multiply() | 返回按元素多重连接后的字符串 |
center() | 居中字符串 |
capitalize() | 将字符串第一个字母转换为大写 |
title() | 将字符串的每个单词的第一个字母转换为大写 |
lower() | 数组元素转换为小写 |
upper() | 数组元素转换为大写 |
split() | 指定分隔符对字符串进行分割,并返回数组列表 |
splitlines() | 返回元素中的行列表,以换行符分割 |
strip() | 移除元素开头或者结尾处的特定字符 |
join() | 通过指定分隔符来连接数组中的元素 |
replace() | 使用新字符串替换字符串中的所有子字符串 |
decode() | 数组元素依次调用str.decode |
encode() | 数组元素依次调用str.encode |
numpy.char.add()
依次对两个数组的元素进行字符串连接
import numpy as np
print ('连接两个字符串')
print (np.char.add(['hello'],['word']))
print ('连接示列')
print (np.char.add(['hello', 'hi'],['word','world']))
连接两个字符串
['helloword']
连接示列
['helloword' 'hiworld']
numpy.char.multiply()
执行多重连接
import numpy as np
print (np.char.multiply('python', 5))
pythonpythonpythonpythonpython
numpy.char.center()
函数用于将字符串居中, 并使用指定字符在左侧和右侧进行填充
np.char.center(str, width, fillchar)
str: 字符串, width:长度, fillchar: 填充字符
import numpy as np
print (np.char.center('python', 20, fillchar = '*'))
*******python*******
numpy.char.capitalize()
将字符串的第一个字母装换为大写
>>> import numpy as np
>>> print (np.char.capitalize('python')
... )
Python
numpy.char.title()
字符串的每个单词的第一个字母转换为大写
>>> import numpy as np
>>> print (np.char.title('i love python'))
I Love Python
numpy.char.lower()
对数组的每个元素转换为小写, 对每个元素调用str.lower
>>> print (np.char.lower(['HELLO','PYTHON'])) # 操作数组
['hello' 'python']
>>> print (np.char.lower('PYTHON')) # 操作字符串
python
numpy.char.upper()
将数组每个元素转换成大写, 同char.lower()
numpy.char.split()
通过指定分隔符对字符串进行分割,并返回数组。默认情况下,分隔符为空格。
>>> print (np.char.split('i love python')) # 默认分割符为空格
['i', 'love', 'python']
>>> print (np.char.split('pigdaqiang.top', sep = '.')) # 指定分隔符为 .
['pigdaqiang', 'top']
numpy.char.splitlines()
以换行符作为分隔符, 并返回数组
>>> print (np.char.splitlines('i\r\nlove python'))
['i', 'love python']
>>> print (np.char.splitlines('i\rlove python'))
['i', 'love python']
注意区别linux下和win下换行符的区别 \r
\n
\r\n
numpy.char.strip()
用于移除开头或结尾处的特定字符
>>> print (np.char.strip('hhello', 'h')) # 移除字符串头尾的h字符
ello
>>>
>>> print (np.char.strip(['hello','hi','high'],'h')) # 移除数组元素头尾的a字符
['ello' 'i' 'ig']
>>>
numpy.char.join()
通过指定分割符来连接数组中的元素或字符串
>>> print (np.char.join(':','hello'))
h:e:l:l:o
>>> print (np.char.join([':','*'],['hello','python']))
['h:e:l:l:o' 'p*y*t*h*o*n']
>>>
numpy.char.replace()
使用新字符串代替字符串中的所有子字符串
>>> print (np.char.replace('i love python',' ','*'))
i*love*python
>>>
numpy.char.encode()
函数对数组中的每个元素调用str.encode函数, 默认编码是utf-8, 可以使用标准python库中的编解码器
>>> print (np.char.encode('hello','cp500'))
b'\x88\x85\x93\x93\x96'
>>>
numpy.char.decode()
函数对编码的元素进行str.encode()解码
>>> a = np.char.encode('hello', 'cp500')
>>> print (a, np.char.decode(a, 'cp500'))
b'\x88\x85\x93\x93\x96' hello
>>>
numpy数学函数
NumPy 包含大量的各种数学运算的函数,包括三角函数,算术运算的函数,复数处理函数等。
三角函数
NumPy 提供了标准的三角函数:sin()、cos()、tan()。
import numpy as np
a = np.array([0,20,45,60,90])
print ('不同角度的正弦值')
# 通过乘pi/180转化为弧度
print (np.sin(a*np.pi/180))
print ('\n')
print ('数组中角度的余玄值')
print (np.cos(a*np.pi/180))
print ('\n')
print ('数组中角度的正切值')
print (np.tan(a*np.pi/180))
不同角度的正弦值
[ 0. 0.34202014 0.70710678 0.8660254 1. ]
数组中角度的余玄值
[ 1.00000000e+00 9.39692621e-01 7.07106781e-01 5.00000000e-01
6.12323400e-17]
数组中角度的正切值
[ 0.00000000e+00 3.63970234e-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 ('\n')
print ('计算角度的反正弦,返回值以弧度为单位:')
inv = np.arcsin(sin)
print (inv)
print ('\n')
print ('通过转化为角度制来检查结果:')
print (np.degrees(inv))
print ('\n')
print ('arccos 和 arctan 函数行为类似:')
cos = np.cos(a*np.pi/180)
print (cos)
print ('\n')
print ('反余弦:')
inv = np.arccos(cos)
print (inv)
print ('\n')
print ('角度制单位:')
print (np.degrees(inv))
print ('\n')
print ('tan 函数:')
tan = np.tan(a*np.pi/180)
print (tan)
print ('\n')
print ('反正切:')
inv = np.arctan(tan)
print (inv)
print ('\n')
print ('角度制单位:')
print (np.degrees(inv))
含有正弦值的数组:
[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.]
舍入函数
函数返回指定数字的四舍五入值
numpy.around(a, decimals)
a
数组
decimals
舍入的小数位数, 默认值为0, 如果为负数, 整数将四舍五入到小数点的左侧
import numpy as np
a = np.array([1.0, 5.55, 123, 0.567, 25.532])
print ('原数组')
print (a)
print ('\n')
print ('舍入后')
print (np.around(a))
print (np.around(a, decimals = 1))
print (np.around(a, decimals = -1))
原数组
[ 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.]
numpy.floor()
返回小于或者等于指定表达式的最大整数, 向下取整
import numpy as np
a = np.array([-1.7, 1.5, -0.2, 0.6, 10])
print ('提供的数组')
print (a)
print ('\n')
print ('修改后的数组')
print (np.floor(a))
提供的数组
[ -1.7 1.5 -0.2 0.6 10. ]
修改后的数组
[ -2. 1. -1. 0. 10.]
numpy.ceil()
返回大于或者等于指定表达式的最小整数, 即向上取整. 用法同floor
numpy算术函数
算术函数包含简单的加减乘除:add(), substract(), multiply(), divide()
数组必须具有相同形状或符合数组广播 规则
import numpy as np
a = np.arange(9, dtype = np.float_).reshape(3,3)
print ('第一个数组')
print (a)
print ('\n')
print ('第二个数组')
b = np.array([10,10,10])
print (b)
print ('\n')
print ('两个数组相加')
print (np.add(a,b))
print ('\n')
print ('两个数组相减')
print (np.subtract(a,b))
print ('\n')
print ('两个数组相乘')
print (np.multiply(a,b))
print ('\n')
print ('两个数组 相除:')
print (np.divide(a,b))
第一个数组
[[ 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]]
numpy.reciprocal()
返回参数逐元素的倒数, 1/4倒数4/1
import numpy as np
a = np.array([0.25, 1.33, 1, 100])
print (a)
print ('倒数')
print (np.reciprocal(a))
[ 0.25 1.33 1. 100. ]
倒数
[ 4. 0.7518797 1. 0.01 ]
numpy.power()
函数将第一个输入数组中的元素作为底数, 计算它与第二个输入数组中相应元素的幂
import numpy as np
a = np.array([10,100,1000])
print ('数组')
print (a)
print ('\n')
print ('调用power')
print (np.power(a,2))
print ('\n')
print ('第二个数组')
b = np.array([1,2,3])
print (b)
print ('再次调用power函数')
print (np.power(a,b))
数组
[ 10 100 1000]
调用power
[ 100 10000 1000000]
第二个数组
[1 2 3]
再次调用power函数
[ 10 10000 1000000000]
numpy.mod()
计算输入数组中相应元素的相除后的余数, numpy.remainder()也产生相同的结果
import numpy as np
a = np.array([10,20,30])
b = np.array([3,5,7])
print ('调用mod')
print (np.mod(a,b))
print ('调用remainder')
print (np.remainder(a,b))
调用mod
[1 0 2]
调用remainder
[1 0 2]
numpy 统计函数
从数组中查找最小元素, 最大元素, 百分位标准差, 和方差灯
numpy.amin()和numpy.amax()
numpy.amin() 用于计算数组中的元素沿指定轴的最小值。
numpy.amax() 用于计算数组中的元素沿指定轴的最大值。
import numpy as np
a = np.array([[3,5,7],[8,4,3],[2,4,9]])
print ('原数组')
print (a)
print ('\n')
print ('调用amin()函数')
print (np.amin(a,1))
print ('\n')
print ('再次调用amin')
print (np.amin(a,0))
print ('调用amax')
print (np.amax(a))
print ('\n')
print ('再次调用amax')
print (np.amax(a, axis = 0))
原数组
[[3 5 7]
[8 4 3]
[2 4 9]]
调用amin()函数
[3 3 2]
再次调用amin
[2 4 3]
调用amax
9
再次调用amax
[8 5 9]
numpy.ptp()
计算元素最大值与最小值的差(最大值-最小值)
import numpy as np
a = np.array([[3,5,7],[8,4,3],[2,4,9]])
print (a)
print ('\n')
print ('调用ptp函数')
print (np.ptp(a))
print ('\n')
print ('沿轴1调用ptp函数')
print (np.ptp(a,axis = 1))
print ('\n')
print ('沿轴0调用ptp函数')
print (np.ptp(a,axis = 0))
[[3 5 7]
[8 4 3]
[2 4 9]]
调用ptp函数
7
沿轴1调用ptp函数
[4 5 7]
沿轴0调用ptp函数
[6 1 6]
numpy.percentile()
百分数是统计中使用的度量, 表示小于这个值的观察值的百分比.
numpy.percentile(a, q, axis)
a
输入数组
q
要计算的百分位数, 在0-100之间
axis
沿着它计算百分位数的轴
首先明确百分位数:
第 p 个百分位数是这样一个值,它使得至少有 p% 的数据项小于或等于这个值,且至少有 (100-p)% 的数据项大于或等于这个值。
举个例子:高等院校的入学考试成绩经常以百分位数的形式报告。比如,假设某个考生在入学考试中的语文部分的原始分数为 54 分。相对于参加同一考试的其他学生来说,他的成绩如何并不容易知道。但是如果原始分数54分恰好对应的是第70百分位数,我们就能知道大约70%的学生的考分比他低,而约30%的学生考分比他高。
这里的 p = 70。
import numpy as np
a = np.array([[10,7,4], [3,2,1]])
print (a)
print ('调用percentile函数')
# 50%的分位数就是a里排序之后的中位数
print (np.percentile(a, 50))
# axis为0 , 在纵列上求
print (np.percentile(a,50, axis = 0))
# 横行上求
print (np.percentile(a, 50, axis = 1))
# 维度不变
print (np.percentile(a, 50, axis = 1, keepdims = True))
[[10 7 4]
[ 3 2 1]]
调用percentile函数
3.5
[ 6.5 4.5 2.5]
[ 7. 2.]
[[ 7.]
[ 2.]]
numpy.median()
函数用于计算数组a中元素的中位数(中值)
import numpy as np
a = np.array([[30,65,70,],[80, 95, 10], [50, 90, 60]])
print ('原数组')
print (a)
print ('\n')
print ('调用median')
print (np.median(a))
print ('\n')
print ('沿轴0调用median函数')
print (np.median(a, axis = 0))
print ('\n')
print ('沿轴1调用median函数')
print (np.median(a, axis = 1))
原数组
[[30 65 70]
[80 95 10]
[50 90 60]]
调用median
65.0
沿轴0调用median函数
[ 50. 90. 60.]
沿轴1调用median函数
[ 65. 80. 60.]
numpy.mean()
函数返回数组中元素的算术平均值, 如果提供了轴, 则沿其计算, 算术平均值是沿轴的元素总和除以元素的数量
import numpy as np
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
print ('我们的数组是')
print (a)
print ('\n')
print ('调用mean')
print (np.mean(a))
print ('\n')
print ('沿轴0调用mean函数')
print (np.mean(a, axis = 0))
print ('\n')
print ('沿轴1 调用mean函数')
print (np.mean(a, axis = 1))
我们的数组是
[[1 2 3]
[3 4 5]
[4 5 6]]
调用mean
3.66666666667
沿轴0调用mean函数
[ 2.66666667 3.66666667 4.66666667]
沿轴1 调用mean函数
[ 2. 4. 5.]
numpy.average()
函数根据在另一个数组中给出的各自的权重计算数组中元素的加权平均值。
该函数可以接受一个轴参数。 如果没有指定轴,则数组会被展开。
加权平均值即将各数值乘以相应的权数,然后加总求和得到总体值,再除以总的单位数。
考虑数组[1,2,3,4]和相应的权重[4,3,2,1],通过将相应元素的乘积相加,并将和除以权重的和,来计算加权平均值。
加权平均值 = (1*4+2*3+3*2+4*1)/(4+3+2+1)
import numpy as np
a = np.array([1,2,3,4])
print ('原数组')
print (a)
print ('\n')
print ('调用average函数')
print (np.average(a))
print ('\n')
# 不指定权重时相当于mean函数
wts = np.array([4,3,2,1])
print ("再次调用average函数")
print (np.average(a, weights = wts))
print ('\n')
# 如果returned参数设为true, 则返回权重的和
print ('权重的和:')
print (np.average([1,2,3,4], weights = [4,3,2,1], returned = True))
原数组
[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 ('\n')
print ('修改之后的数组')
wt = np.array([3,5])
print (np.average(a, axis = 1, weights = wt))
print ('\n')
print ('修改后的数组')
print (np.average(a, axis = 1, weights = wt, returned = True))
原数组
[[0 1]
[2 3]
[4 5]]
修改之后的数组
[ 0.625 2.625 4.625]
修改后的数组
(array([ 0.625, 2.625, 4.625]), array([ 8., 8., 8.]))
标准差std()
标准差是一组数据平均值分散程度的一种度量。
标准差是方差的算术平方根。
标准差公式如下:
std = sqrt(mean((x - x.mean())**2))
如果数组是 [1,2,3,4],则其平均值为 2.5。 因此,差的平方是 [2.25,0.25,0.25,2.25],并且其平均值的平方根除以 4,即 sqrt(5/4) ,结果为 1.1180339887498949。
import numpy as np
print (np.std([1,2,3,4]))
1.11803398875
方差var()
统计中的方差(样本方差)是每个样本值与全体样本值的平均数之差的平方值的平均数,即 mean((x - x.mean())** 2)。
换句话说,标准差是方差的平方根。
import numpy as np
print (np.var([1,2,3,4]))
1.25
numpy排序, 条件刷选函数
NumPy 提供了多种排序的方法。 这些排序函数实现不同的排序算法,每个排序算法的特征在于执行速度,最坏情况性能,所需的工作空间和算法的稳定性。 下表显示了三种排序算法的比较。
种类 | 速度 | 最坏情况 | 工作空间 | 稳定性 |
---|---|---|---|---|
'quicksort' (快速排序) | 1 | O(n^2) | 0 | 否 |
'mergesort' (归并排序) | 2 | O(n*log(n)) | ~n/2 | 是 |
'heapsort' (堆排序) | 3 | O(n*log(n)) | 0 | 否 |
numpy.sort()
返回输入数组的排序副本
numpy.sort(a, axis, kind, order)
a
要排序的数组
axis
沿着它排序数组的轴, 如果没有数组会被展开, 沿着最后的轴排序, axis = 0 按列排序, axis=1 按行
kind
默认为quicksort
(快速排序)
order
如果数组包含字段, 则是要排序的字段
import numpy as np
a = np.array([[3,7],[9,1]])
print ('原数组')
print (a)
print ('\n')
print ('调用sort函数')
print (np.sort(a))
print ('\n')
print ('按列排序')
print (np.sort(a, axis = 0))
print ('\n')
# 在sort函数中排序字段
dt = np.dtype([('name','S10'), ('age', int)])
a = np.array([('raju', 21), ('anil', 25), ('ravi',17), ('amar', 27)], dtype = d
t)
print ('原数组')
print (a)
print ('\n')
print ('按name排序')
print (np.sort(a,order = 'name'))
原数组
[[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)]
numpy.argsort()
返回数组值从小到大的索引值
import numpy as np
x = np.array([3,1,2])
print ('原数组')
print (x)
print ('\n')
print ('对x调用argsort函数')
y = np.argsort(x)
print (y)
print ('\n')
print ('以排序后的顺序重构原数组')
print (x[y])
print ('\n')
print ('使用循环重构原数组')
for i in y:
print (x[i], end = ' ')
原数组
[3 1 2]
对x调用argsort函数
[1 2 0]
以排序后的顺序重构原数组
[1 2 3]
使用循环重构原数组
1 2 3
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 ('\n')
print ('使用这个索引来获取排序后的数据')
print ([nm[i] + ', ' + dv[i] for i in ind])
调用lexsort函数
[3 1 0 2]
使用这个索引来获取排序后的数据
['amar, f.y.', 'anil, s.y.', 'raju, f.y.', 'ravi, s.y.']
上面传入一个np.lexsort的是一个ruple, 排序是首先排nm, 顺序为amar, anil, raju, ravi 综上排序结果为[3 1 0 2]
msort sort_complex partition argpartition
函数 | 描述 |
---|---|
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 指定算法沿着指定轴对数组进行分区 |
>>> import numpy as np
>>> np.sort_complex([5,3,6,2,1])
array([ 1.+0.j, 2.+0.j, 3.+0.j, 5.+0.j, 6.+0.j])
>>> np.sort_complex([1+2j, 2-1j, 3-2j, 3-3j, 3+5j])
array([ 1.+2.j, 2.-1.j, 3.-3.j, 3.-2.j, 3.+5.j])
>>>
import numpy as np
a = np.array([3,4,2,1])
print (np.partition(a,3)) # 将数组a中的所有元素(包括重复元素) 从小到大排列, 3
表示的是排序数组索引为3的数字, 比该数字小的排在该数字前面, 比该数字大的排在该数
字的后面
print (np.partition(a, (1,3))) # 小于1的在前面, 大于3的在后面, 1和3之间的在中间
'''
找到数组的第三小(index=2)的值和第二大index=-2的值
'''
arr = np.array([46,57,23,39,1,10,0,120])
print (arr[np.argpartition(arr, 2)[2]])
print (arr[np.argpartition(arr, -2)[-2]])
'''
同时找到第三和第四小的值, 注意这里用[2,3]同时将第3和第四小的排序, 然后可以分别
通过下标[2]和[3]取得
'''
print (arr[np.argpartition(arr, [2,3])[2]])
print (arr[np.argpartition(arr, [2,3])[3]])
[2 1 3 4]
[1 2 3 4]
10
57
10
23
numpy.argmax()和numpy.argmin()
函数分别沿给定轴返回最大和最小值的索引
import numpy as np
a = np.array([[30,40,70],[80,20,10],[50,90,60]])
print ('原数组')
print (a)
print ('\n')
print ('调用argmax函数')
print (np.argmax(a))
print ('\n')
print ('展开数组')
print (a.flatten())
print ('\n')
print ('沿轴0的最大值索引')
maxindex = np.argmax(a, axis = 0)
print (maxindex)
print ('\n')
print ('沿轴1的最大值索引')
maxindex = np.argmax(a, axis = 1)
print (maxindex)
print ('\n')
print ('调用argmin函数')
minindex = np.argmin(a)
print (minindex)
print ('\n')
print ('展开数组中的最小值')
print (a.flatten()[minindex])
print ('\n')
print ('沿轴0的最小值索引')
minindex = np.argmin(a, axis = 0)
print (minindex)
print ('\n')
print ('沿轴1的最小值索引')
minindex = np.argmin(a, axis = 1)
print (minindex)
原数组
[[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]
numpy.nonzero()
函数返回输入数组中非0元素的索引
import numpy as np
a = np.array([[30,40,0],[0,20,10],[50,0,60]])
print ('我们的数组是')
print (a)
print ('\n')
print ('调用nonzero函数')
print (np.nonzero(a))
我们的数组是
[[30 40 0]
[ 0 20 10]
[50 0 60]]
调用nonzero函数
(array([0, 0, 1, 1, 2, 2]), array([0, 1, 1, 2, 0, 2]))
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])
我们的数组是
[[ 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.]
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))
原数组
[[ 0. 1. 2.]
[ 3. 4. 5.]
[ 6. 7. 8.]]
按元素的条件值
[[ True False True]
[False True False]
[ True False True]]
使用条件提取元素
[ 0. 2. 4. 6. 8.]
numpy字节交换
在几乎所有的机器上,多字节对象都被存储为连续的字节序列。字节顺序,是跨越多字节的程序对象的存储规则。
- **大端模式:**指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;这和我们的阅读习惯一致。
- **小端模式:**指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低。
例如在 C 语言中,一个类型为 int 的变量 x 地址为 0x100,那么其对应地址表达式&x的值为 0x100。且x的四个字节将被存储在存储器的 0x100, 0x101, 0x102, 0x103位置。
numpy.ndarray.byteswap()
将ndarray中每个元素中的字节进行大小端转换
import numpy as np
a = np.array([1, 256, 8755], dtype = np.int16)
print ('原数组')
print (a)
print ('以16进制表示内存中的数据')
print (map(hex, a))
# btypeswap()函数通过传入true来原地交换
print ('调用byteswap函数')
print (a.byteswap(True))
print ('16进制')
print (map(hex, a))
# 字节交换
原数组
[ 1 256 8755]
以16进制表示内存中的数据
<map object at 0x7fc8ff886898>
调用byteswap函数
[ 256 1 13090]
16进制
<map object at 0x7fc8fa7d2ef0>
副本和视图(深拷贝和浅拷贝)
副本是一个数据的完整的拷贝,如果我们对副本进行修改,它不会影响到原始数据,物理内存不在同一位置。
视图是数据的一个别称或引用,通过该别称或引用亦便可访问、操作原有数据,但原有数据不会产生拷贝。如果我们对视图进行修改,它会影响到原始数据,物理内存在同一位置。
视图一般发生在:
- 1、numpy 的切片操作返回原数据的视图。
- 2、调用 ndarray 的 view() 函数产生一个视图。
副本一般发生在:
- Python 序列的切片操作,调用deepCopy()函数。
- 调用 ndarray 的 copy() 函数产生一个副本。
无复制
简单的赋值不会创建数组对象的副本。 相反,它使用原始数组的相同id()来访问它。 id()返回 Python 对象的通用标识符,类似于 C 中的指针。
此外,一个数组的任何变化都反映在另一个数组上。 例如,一个数组的形状改变也会改变另一个数组的形状。
矩阵(Matrix)
NumPy 中包含了一个矩阵库 numpy.matlib,该模块中的函数返回的是一个矩阵,而不是 ndarray 对象。
一个 的矩阵是一个由行(row)列(column)元素排列成的矩形阵列。
矩阵里的元素可以是数字、符号或数学式。以下是一个由 6 个数字元素构成的 2 行 3 列的矩阵:
matlib.empty()
返回一个新矩阵
numpy.matlib.empty(shape, dtype, order)
shape
定义新矩阵的整数或 整数元组
dtype
可选, 数据类型
order
c或者f
import numpy.matlib
import numpy as np
print (np.matlib.empty((2,2)))
# 填充为随机数
[[ 6.91000091e-310 4.68077452e-310]
[ 6.90999951e-310 0.00000000e+000]]
numpy.matlib.zeros()
创建一个以0填充的矩阵
import numpy.matlib
import numpy as np
print (np.matlib.zeros((2,2)))
[[ 0. 0.]
[ 0. 0.]]
numpy.matlib.ones()
创建一个以1填充的矩阵
numpy.matlib.ones((2,2))
numpy.matlib.eye()
返回一个矩阵, 对角元素为1, 其他位置为0
numpy.matlib.eye(n, M, k, dtype)
n
返回矩阵的行数
M
返回矩阵的列数, 默认为n
k
对角线的索引
dtype
数据类型
import numpy.matlib
import numpy as np
print (np.matlib.eye(n = 3, M = 4, k = 0, dtype = float))
[[ 1. 0. 0. 0.]
[ 0. 1. 0. 0.]
[ 0. 0. 1. 0.]]
numpy.matlib.identity()
返回给定大小的单位矩阵
单位矩阵是个方阵, 从左上角到右下角的对角线(称为主对角线)上的元素均为1, 除此以外全都为0
import numpy.matlib
import numpy as np
print (np.matlib.identity(5, dtype = float))
# 大小为5, 类型为浮点数
[[ 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.]]
numpy.matlib.rand()
创建一个给定大小的矩阵, 数据是随机填充的
numpy.matlib.rand(3,3)
矩阵是二维的, ndarray是一个n维数组, 两个对象是可互换的
import numpy.matlib
import numpy as np
i = np.matrix('1,2;3,4')
print (i)
[[1 2]
[3 4]]
j = np.asarray(i)
print (j)
[[1 2]
[3 4]]
k = np.asmatrix(j)
print (k)
[[1 2]
[3 4]]
线性代数
NumPy 提供了线性代数函数库 linalg,该库包含了线性代数所需的所有功能,可以看看下面的说明:
函数 | 描述 |
---|---|
dot | 两个数组的点积,即元素对应相乘。 |
vdot | 两个向量的点积 |
inner | 两个数组的内积 |
matmul | 两个数组的矩阵积 |
determinant | 数组的行列式 |
solve | 求解线性矩阵方程 |
inv | 计算矩阵的乘法逆矩阵 |
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()的计算结果
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))
[[37 40]
[85 92]]
计算公式
[[1*11+2*13, 1*12+2*14],[3*11+4*13, 3*12+4*14]]
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))
130
计算公式
1*11 + 2*12 + 3*13 + 4*14 = 130
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
2
多维数组::
import numpy as np
a = np.array([[1,2], [3, 4 ]])
print ('数组a')
print (a)
b = np.array([[11, 22], [13, 14]])
print ('数组b')
print (b)
print ('内积')
print (np.inner(a, b))
数组a
[[1 2]
[3 4]]
数组b
[[11 22]
[13 14]]
内积
[[ 55 41]
[121 95]]
1*11+2*12, 1*13+2*14
3*11+4*12, 3*13+4*14
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))
[[4 1]
[2 2]]
二维和一维运算
import numpy.matlib
import numpy as np
a = [[1, 0], [0, 1]]
b = [1, 2]
print (np.matmul(a, b))
print (np.matmul(b, a))
[1 2]
[1 2]
维度大于二
import numpy.matlib
import numpy as np
a = np.arange(8).reshape(2,2,2)
b = np.arange(4).reshape(2,2)
print (np.matmul(a, b))
[[[ 2 3]
[ 6 11]]
[[10 19]
[14 27]]]
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))
-2.0
import numpy as np
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))
[[ 6 1 1]
[ 4 -2 5]
[ 2 8 7]]
-306.0
-306
numpy.linalg.solve()
给出了矩阵形式的线性方程的解
x + y + z = 6
2y + 5z = -4
2x + 5y - z = 27
如果矩阵成为A, X和B方程变为
AX = B
或
X = A^(-1)B
numpy.linalg.inv()
numpy.linalg.inv() 函数计算矩阵的乘法逆矩阵。
逆矩阵(inverse matrix):设A是数域上的一个n阶矩阵,若在相同数域上存在另一个n阶矩阵B,使得: AB=BA=E ,则我们称B是A的逆矩阵,而A则被称为可逆矩阵。注:E为单位矩阵。
import numpy as np
x = np.array([[1, 2], [3, 4]])
y = np.linalg.inv(x)
print (x)
print (y)
print (np.dot(x, y))
[[1 2]
[3 4]]
[[-2. 1. ]
[ 1.5 -0.5]]
[[ 1.00000000e+00 1.11022302e-16]
[ 0.00000000e+00 1.00000000e+00]]
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的解
数组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)
numpy IO
可以读写磁盘上的文本数据或者二进制数据. 为ndarray对象引入了一个简单的文本格式, npy
npy文件用于存储重建ndarray所需的数据, 图形, dtype和其他信息.
常用IO函数有:
- load() 和 save() 函数是读写文件数组数据的两个主要函数,默认情况下,数组是以未压缩的原始二进制格式保存在扩展名为 .npy 的文件中。
- savze() 函数用于将多个数组写入文件,默认情况下,数组是以未压缩的原始二进制格式保存在扩展名为 .npz 的文件中。
- loadtxt() 和 savetxt() 函数处理正常的文本文件(.txt 等)
numpy.save()
将数组保存到以.npy为扩展名的文件中
numpy.save(file, arr, allow_pickle=True, fix_imports=True)
- file:要保存的文件,扩展名为 .npy,如果文件路径末尾没有扩展名 .npy,该扩展名会被自动加上。
- arr: 要保存的数组
- allow_pickle: 可选,布尔值,允许使用 Python pickles 保存对象数组,Python 中的 pickle 用于在保存到磁盘文件或从磁盘文件读取之前,对对象进行序列化和反序列化。
- fix_imports: 可选,为了方便 Pyhton2 中读取 Python3 保存的数据。
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)
pig@deep:~/Desktop/note/python/numpy$ cat outfile.npy
�NUMPYF{'descr': '<i8', 'fortran_order': False, 'shape': (5,), }
pig@deep:~/Desktop/note/python/numpy$ cat outfile2.npy
�NUMPYF{'descr': '<i8', 'fortran_order': False, 'shape': (5,), }
p
可以看出文件是乱码的,因为它们是 Numpy 专用的二进制格式后的数据。
我们可以使用 load() 函数来读取数据就可以正常显示了:
import numpy as np
b = np.load('outfile.npy')
print (b)
[1 2 3 4 5]
numpy.savez
将多个数组保存到以npz为拓展名的文件中
numpy.savez(file, *arg, **kwds)
- file:要保存的文件,扩展名为 .npz,如果文件路径末尾没有扩展名 .npz,该扩展名会被自动加上。
- args: 要保存的数组,可以使用关键字参数为数组起一个名字,非关键字参数传递的数组会自动起名为 arr_0, arr_1, … 。
- kwds: 要保存的数组使用关键字名称。
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('savez.npz', a, b, sin_array = c)
r = np.load('savez.npz')
print (r.files) # 查看个数组名称
print (r['arr_0']) # 数组a
print (r['arr_1'])
print (r['sin_array']) # 数组c
['arr_1', 'sin_array', 'arr_0']
[[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]
savetxt()
是以简单的文本格式存储数据 , 对应的使用loadtxt函数来获取数据
np.loadtxt(FILENAME, dtype=int, delimiter='')
np.savetxt(FILENAME, a, fmt='%d', delimiter=",")
delimiter可以指定各种分隔符, 针对特定列的转换器函数, 需要跳过的行数等.
import numpy as np
a = np.array([1,2,3,4,5])
np.savetxt('out.txt', a)
b = np.loadtxt('out.txt')
print (b)
[ 1. 2. 3. 4. 5.]
使用delimiter参数:
import numpy as np
a = np.arange(0, 10, 0.5).reshape(4,-1)
np.savetxt('out2.txt', a, fmt="%d", delimiter="*") # 改为保存整数, 以逗号分隔
b = np.loadtxt("out2.txt", delimiter="*") # load时也要指定为相同符号分隔
print (b)
[[ 0. 0. 1. 1. 2.]
[ 2. 3. 3. 4. 4.]
[ 5. 5. 6. 6. 7.]
[ 7. 8. 8. 9. 9.]]
matplotlib
Matplotlib 是 Python 的绘图库。 它可与 NumPy 一起使用,提供了一种有效的 MatLab 开源替代方案。 它也可以和图形工具包一起使用,如 PyQt 和 wxPython。
wim下安装matplotlib:
python -m pip install -U pip setuptools
python -m pip install matplotlib
linux下:
sudo apt-get install python-matplotlib
mac:
sudo python -mpip install matplotlib
查看是否安装完成:
python -m pip list | grep matplotlib
matplotlib 2.2.4
实例
import numpy as np
from matplotlib import pyplot as plt
x = np.arange(1,11)
y = 2 * x + 5
plt.title("test demo")
plt.xlabel("x axis caption")
plt.ylabel("y axis caption")
plt.plot(x, y)
plt.show()
以上实例中, np.arange()函数创建x轴上的值, y轴上对应值存储在另一个数组对象y中, 这些值使用matplotlib软件包的pyplot子模块plot()函数来绘制, 由show()函数来显示
图形中文显示
默认情况下不支持中文, 可以使用以下方法(下载字体)https://www.fontpalace.com/font-details/SimHei/
SimHei.ttf文件放在当前执行的代码文件中.
import numpy as np
from matplotlib import pyplot as plt
import matplotlib
# fname 为 你下载的字体库路径,注意 SimHei.ttf 字体的路径
zhfont1 = matplotlib.font_manager.FontProperties(fname="SimHei.ttf")
x = np.arange(1,11)
y = 2 * x + 5
plt.title("测试", fontproperties=zhfont1)
# fontproperties 设置中文显示,fontsize 设置字体大小
plt.xlabel("x 轴", fontproperties=zhfont1)
plt.ylabel("y 轴", fontproperties=zhfont1)
plt.plot(x,y)
plt.show()
此外还可以使用系统字体:
from matplotlib import pyplot as plt
import matplotlib
a = sorted([f.name for f in matplotlib.font_manager.fontManager.ttflist])
for i in a:
print (i)
打印出你的font_manage的ttflist中所有注册的名字, 找一个看中文字体例如:STFangsong(仿宋)然后添加以下代码即可:
plt.rcParams['font.family']=['STFangsong']
实例:
import numpy as np
from matplotlib import pyplot as plt
import matplotlib
# 导入系统字体库
plt.rcParams['font.family']=['CESI_HT_GB18030']
x = np.arange(0, 2 * np.pi, 0.001)
y = np.sin(x)
plt.title("测试")
plt.xlabel("x轴")
plt.ylabel("y轴")
plt.plot(x, y)
plt.show()
作为线性图的替代,可以通过向 plot() 函数添加格式字符串来显示离散值。 可以使用以下格式化字符。
字符 | 描述 |
---|---|
'-' | 实线样式 |
'--' | 短横线样式 |
'-.' | 点划线样式 |
':' | 虚线样式 |
'.' | 点标记 |
',' | 像素标记 |
'o' | 圆标记 |
'v' | 倒三角标记 |
'^' | 正三角标记 |
'<' | 左三角标记 |
'>' | 右三角标记 |
'1' | 下箭头标记 |
'2' | 上箭头标记 |
'3' | 左箭头标记 |
'4' | 右箭头标记 |
's' | 正方形标记 |
'p' | 五边形标记 |
'*' | 星形标记 |
'h' | 六边形标记 1 |
'H' | 六边形标记 2 |
'+' | 加号标记 |
'x' | X 标记 |
'D' | 菱形标记 |
'd' | 窄菱形标记 |
'|' | 竖直线标记 |
'_' | 水平线标记 |
以下是颜色的缩写:
字符 | 颜色 |
---|---|
'b' | 蓝色 |
'g' | 绿色 |
'r' | 红色 |
'c' | 青色 |
'm' | 品红色 |
'y' | 黄色 |
'k' | 黑色 |
'w' | 白色 |
要显示圆来代表点,而不是上面示例中的线,请使用 ob 作为 plot() 函数中的格式字符串。
import numpy as np
from matplotlib import pyplot as plt
x = np.arange(0, 2 * np.pi, 0.1)
y = np.cos(x)
plt.title("sin")
plt.xlabel("x axis caption")
plt.ylabel("y axis caption")
plt.plot(x, y, ".b")
plt.show()
绘制正弦波
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(0, 3 * np.pi, 0.1)
y = np.sin(x)
plt.title("sine")
plt.plot(x, y, '.b')
plt.show()
subplot()
允许在同一图中绘制不同的东西
正弦余弦
import numpy as np
import matplotlib.pyplot as plt
# 计算正弦和余弦曲线上的点x和y坐标
x = np.arange(0, 2 * np.pi, 0.1)
y_sin = np.sin(x)
y_cos = np.cos(x)
# 建立subplot网格 高为1, 宽为2
# 激活第一个subplot
plt.subplot(1, 2, 1)
# 绘制第一个图像
plt.plot(x, y_sin)
plt.title("sine")
# 激活第二个subplot并绘制第二个图像
plt.subplot(1, 2, 2)
plt.plot(x, y_cos)
plt.title("cosine")
# 展示图像
plt.show()
plt.subplot(1,2,1)
不同参数的区别
bar()
pyplot 子模块提bar()函数来生成条形图
实现两组x 和y数组的条形图
import matplotlib.pyplot as plt
x = [5, 8, 10]
y = [12, 16, 6]
x2 = [6, 9, 11]
y2 = [6, 15, 7]
plt.bar(x, y, align = 'center')
plt.bar(x2, y2, color = 'g', align = 'center')
plt.title('bar graph')
plt.ylabel('Y axis')
plt.xlabel('x axis')
plt.show()
numpy.histogram()
是数据频率分布的图形表示, 水平尺寸相等的矩形对应于类间隔, 称为bin, 变量height对应与频率
将输入数组和bin作为两个参数, bin数组中连续元素用作每个bin的边界
a = np.array([22,87,5,43,56,73,55,54,11,20,51,5,79,31,27])
np.histogram(a,bins = [0,20,40,60,80,100])
hist,bins = np.histogram(a,bins = [0,20,40,60,80,100])
print (hist)
print (bins)
[3 4 5 2 1]
[ 0 20 40 60 80 100]
plt()
Matplotlib 可以将直方图的数字表示转换为图形。 pyplot 子模块的 plt() 函数将包含数据和 bin 数组的数组作为参数,并转换为直方图。
from matplotlib import pyplot as plt
import numpy as np
a = np.array([22,87,5,43,56,73,55,54,11,20,51,5,79,31,27])
plt.hist(a, bins = [0,20,40,60,80,100])
plt.title("histogram")
plt.show()
参考教程:菜鸟教程
个人博客
简书numpy学习(一)
简书numpy学习(二)