NumPy
(Numerical Python) 是Python
语言的一个数值计算扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。
NumPy
的前身Numeric
最早是由Jim Hugunin与其它协作者共同开发,2005年,Travis Oliphant在Numeric
中结合了另一个同性质的程序库Numarray
的特色,并加入了其它扩展而开发了NumPy
。NumPy
为开放源代码并且由许多协作者共同维护开发。
NumPy
是一个运行速度非常快的数学库,主要用于数组计算,包含:
ndarray
,对数组进行函数运算;C/C++/Fortran
代码的工具;NumPy
通常与SciPy
(Scientific Python)和Matplotlib
(绘图库)一起使用, 这种组合广泛用于替代MatLab
,是一个强大的科学计算环境,有助于我们通过Python
学习数据科学或者机器学习。
SciPy
是一个开源的Python
算法库和数学工具包。SciPy
包含的模块有最优化、线性代数、积分、插值、特殊函数、快速傅里叶变换、信号处理和图像处理、常微分方程求解和其他科学与工程中常用的计算。
Matplotlib
是Python
编程语言及其数值数学扩展包NumPy
的可视化操作界面。它为利用通用的图形用户界面工具包,如Tkinter
, wxPython
, Qt
或GTK+
向应用程序嵌入式绘图提供了应用程序接(API
)。
标准的Python
中用list
(列表)保存值,可以当做数组使用,但因为列表中的元素可以是任何对象,所以浪费了CPU
运算时间和内存。NumPy诞生为了弥补这些缺陷,它提供了两种基本的对象。
ndarray
:全称(n-dimensional array object)是储存单一数据类型的多维数组;ufunc
:全称(universal function object)它是一种能够对数组进行处理的函数。NumPy
官网(https://numpy.org/)
SciPy
官网(https://scipy.org/)
Matplotlib
官网(https://matplotlib.org/)
NumPy
最重要的一个特点是其N
维数组对象ndarray
,它是一系列同类型数据的集合,以0
下标为开始进行集合中元素的索引。NumPy
里面所有的函数都是围绕ndarray
展开的。
ndarray
对象是用于存放同类型元素的多维数组。
ndarray
中的每个元素在内存中都有相同存储大小的区域。
ndarray
内部由以下内容组成:
dtype
,描述在数组中的固定大小值的格子;shape
)的元组,表示各维度大小的元组;stride
),其中的整数指的是为了前进到当前维度下一个元素需要"跨过"的字节数。跨度可以是负数,这样会使数组在内存中后向移动,切片中 obj[::-1] 或 obj[:,::-1] 就是如此numpy.array()
函数创建创建一个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 指定生成数组的最小维度
# 例子
# dtype参数
import numpy as np
a = np.array([1,2,3], dtype = complex)
print(a)
# 输出结果
[1.+0.j 2.+0.j 3.+0.j]
# 最小维度
import numpy as np
a = np.array([1,2,3,4,5], ndmin = 2)
print(a)
# 输出结果
[[1 2 3 4 5]]
ndarray
对象由计算机内存的连续一维部分组成,并结合索引模式,将每个元素映射到内存块中的一个位置。内存块以行顺序(C
样式)或列顺序(FORTRAN
或MatLab
风格,即前述的F
样式)来保存元素。
numpy.empty()
numpy.zeros()
numpy.ones()
numpy.full()
numpy.random.*
numpy.eye()
(1)numpy.empty()
方法用来创建一个指定形状(shape
)、数据类型(dtype
)且未初始化的数组:
numpy.empty(shape, dtype = float, order = 'C')
# 参数说明
shape 数组形状,可以是int或是元组,也可以是列表,如:(3,4)or 3 or [3,4]
dtype 数据类型,可选
order 有"C"和"F"两个选项,分别代表,行优先和列优先,在计算机内存中的存储元素的顺序。
# 例子
import numpy as np
x = np.empty([3,2], dtype = int)
print(x)
# 输出结果
[[ 6917529027641081856 5764616291768666155]
[ 6917529027641081859 -5764598754299804209]
[ 4497473538 844429428932120]]
注意:数组元素为随机值,因为它们未初始化。
(2)numpy.zeros()
创建指定大小的数组,数组元素以0来填充:
numpy.zeros(shape, dtype = float, order = 'C')
# 参数说明
shape 数组形状
dtype 数据类型,可选
order 'C'用于C的行数组,或者'F'用于FORTRAN的列数组
# 例子
import numpy as np
# 默认为浮点数
x = np.zeros(5)
print(x)
# 设置类型为整数
y = np.zeros((5,), dtype = int)
print(y)
# 自定义类型
z = np.zeros((2,2), dtype = [('x','i4'), ('y','i4')])
print(z)
# 输出结果
[0. 0. 0. 0. 0.]
[0 0 0 0 0]
[[(0, 0) (0, 0)]
[(0, 0) (0, 0)]]
(3)numpy.ones()
创建指定形状的数组,数组元素以1来填充:
numpy.ones(shape, dtype = None, order = 'C')
# 参数说明
shape 数组形状
dtype 数据类型,可选
order 'C' 用于C的行数组,或者'F'用于 FORTRAN 的列数组
# 例子
import numpy as np
# 默认为浮点数
x = np.ones(5)
print(x)
# 自定义类型
x = np.ones([2,2], dtype = int)
print(x)
# 输出结果
[1. 1. 1. 1. 1.]
[[1 1]
[1 1]]
(4)numpy.full()
创建指定形状的数组,数组元素以fill_value
来填充:
numpy.full(shape, fill_value, dtype=None, order='C')
# 参数说明
shape 数组形状
fill_value 填充值(标量或类似数组)
dtype 数据类型,可选
order 'C' 用于C的行数组,或者'F'用于 FORTRAN 的列数组
# 例子
import numpy as np
a = np.full((2,2),np.pi)
b = np.full((2,2),1)
c = np.full((2,2),[1,2])
print(a)
print(b)
print(c)
# 输出结果
[[3.14159265 3.14159265]
[3.14159265 3.14159265]]
[[1 1]
[1 1]]
[[1 2]
[1 2]]
(5)numpy.random.*
在Python
中,有两个模块可以产生随机数:
random
包: 提供一些基本的随机数产生函数,可满足基本需要;numpy.random
:提供一些产生随机数的高级函数,满足高级需求。from numpy import random
# 例子1 Numpy创建标准正态分布数组
# 创建randn(size)服从X~N(0,1)的正态分布随机数组
a = random.randn(2,3)
print(a)
# 输出结果
[[-0.75827863 -0.0696867 -2.23015832]
[-0.57744225 -0.20939873 -1.2368758 ]]
# 例子2 Numpy创建随机分布整数型数组
# 利用randint([low,high],size)创建一个整数型指定范围在[low.high]之间的数组
b=random.randint(100,300,(4,4))
print(b)
# 输出结果
[[130 136 156 208]
[221 241 124 244]
[203 266 160 222]
[142 183 203 215]]
(6)numpy.eye()
import numpy as np
# 创建对角矩阵数组
a = np.eye(5)
print(a)
# 输出结果
[[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
从已有的数组创建数组numpy.asarray()
numpy.frombuffer()
numpy.fromiter()
(1)numpy.asarray()
numpy.asarray()
类似numpy.array()
,但numpy.asarray()
参数只有三个。
numpy.asarray(a, dtype = None, order = None)
# 参数说明
a 任意形式的输入参数,可以是:列表、列表的元组、元组、元组的元组、元组的列表、多维数组
dtype 数据类型,可选
order 可选,有"C"和"F"两个选项,分别代表,行优先和列优先,在计算机内存中的存储元素的顺序。
import numpy as np
# 将列表转换为ndarray
x = [1,2,3]
a1 = np.asarray(x)
a2 = np.asarray(x, dtype = float)
print(a1)
print(a2)
# 将元组转换为ndarray
y = (1,2,3)
b = np.asarray(y)
print(b)
# 将元组列表转换为ndarray
z = [(1,2,3),(4,5)]
c = np.asarray(z)
print(c)
# 输出结果
[1 2 3]
[1. 2. 3.]
[1 2 3]
[(1, 2, 3) (4, 5)]
(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 可以是任意对象,会以流的形式读入。
dtype 返回数组的数据类型,可选
count 读取的数据数量,默认为-1,读取所有数据。
offset 读取的起始位置,默认为0。
# Python3例子
import numpy as np
str = b'Hello World9527'
a = np.frombuffer(str, dtype = 'S1')
print(a)
# 输出结果
[b'H' b'e' b'l' b'l' b'o' b' ' b'W' b'o' b'r' b'l' b'd' b'9' b'5' b'2' b'7']
(3)numpy.fromiter()
numpy.fromiter()
方法从可迭代对象中建立ndarray对象,返回一维数组。
numpy.fromiter(iterable, dtype, count=-1)
# 参数说明
iterable 可迭代对象
dtype 返回数组的数据类型
count 读取的数据数量,默认为-1,读取所有数据
import numpy as np
# 使用range函数创建列表对象
list=range(5)
it=iter(list)
print(it)
# 使用迭代器创建 ndarray
x=np.fromiter(it, dtype = float)
print(x)
# 输出结果
<range_iterator object at 0x0000023512CA7E70>
[0. 1. 2. 3. 4.]
NumPy
从数值范围创建数组numpy.arange()
numpy.linspace()
numpy.logspace()
(1)numpy.arange()
numpy
包中的使用arange
函数创建数值范围并返回ndarray对象,函数格式如下:
numpy.arange(start, stop, step, dtype)
# 根据start与stop指定的范围以及step设定的步长,生成一个ndarray
# 参数说明
start 起始值,默认为0
stop 终止值(不包含)
step 步长,默认为1
dtype 返回ndarray的数据类型,如果没有提供,则会使用输入数据的类型。
import numpy as np
a1 = np.arange(10)
a2 = np.arange(10, dtype = float)
b = np.arange(10, 20)
c = np.arange(10, 20, 2)
print(a1)
print(a2)
print(b)
print(c)
# 输出结果
[0 1 2 3 4 5 6 7 8 9]
[0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]
[10 11 12 13 14 15 16 17 18 19]
[10 12 14 16 18]
(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时,生成的数组中会显示间距,反之不显示。
dtype ndarray的数据类型
# 例子1
import numpy as np
a = np.linspace(1,10,10)
b = np.linspace(1,1,10)
c = np.linspace(10, 20, 5, endpoint = False)
d = np.linspace(10, 20, 5)
print(a)
print(b)
print(c)
print(d)
# 输出结果
[1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[10. 12. 14. 16. 18.]
[10. 12.5 15. 17.5 20. ]
# 例子2
import numpy as np
e1 = np.linspace(1,10,10,retstep= True)
e2 = np.linspace(1,10,5,retstep= True)
print(e1)
print(e2)
# 拓展例子
f = np.linspace(1,10,10).reshape([10,1])
print(f)
#输出结果
(array([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.]), 1.0)
(array([ 1., 3.25, 5.5, 7.75, 10.]), 2.25)
[[ 1.]
[ 2.]
[ 3.]
[ 4.]
[ 5.]
[ 6.]
[ 7.]
[ 8.]
[ 9.]
[10.]]
(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 的底数。
dtype ndarray 的数据类型
import numpy as np
# 默认底数是10
a = np.logspace(1.0, 2.0, num = 10)
# 将对数的底数设置为 2
b = np.logspace(0, 9, 10,base = 2)
print(a)
print(b)
# 输出结果
[ 10. 12.91549665 16.68100537 21.5443469 27.82559402
35.93813664 46.41588834 59.94842503 77.42636827 100. ]
[ 1. 2. 4. 8. 16. 32. 64. 128. 256. 512.]
C语言中可以通过struct关键字定义结构类型。NumPy中也有类似的结构数组。
import numpy as np
# 例子1
student = np.dtype([('name','S20'), ('age', 'i1'), ('marks', 'f4')])
a = np.array([('abc', 21, 50),('xyz', 18, 75)], dtype = student)
print(a)
print(a[0])
# 输出结果
[(b'abc', 21, 50.) (b'xyz', 18, 75.)]
(b'abc', 21, 50.)
# 例子2
persontype = np.dtype({
'names':['name','age','weight'],
'formats':['S30','i','f']})
b = np.array([('Zhang',32,75.5),('Wang',24,65.2)],dtype = persontype)
print(b)
print(b[0])
# 输出结果
[(b'Zhang', 32, 75.5) (b'Wang', 24, 65.2)]
(b'Zhang', 32, 75.5)
Python打印字符串,前面出现
b
:
- b: bytes
- python3.x里默认的str是(py2.x里的)unicode, bytes是(py2.x)的str, b”“前缀代表的就是bytes ;
- python2.x里, b前缀没什么具体意义, 只是为了兼容python3.x的这种写法.
NumPy
支持的数据类型比Python
内置的类型要多很多,基本上可以和C
语言的数据类型对应上,其中部分类型对应为Python
内置的类型。
名称 | 描述 |
---|---|
bool_ |
布尔型数据类型(True 或者 False) |
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 个尾数位 |
数据类型对象(numpy.dtype
类的实例)用来描述与数组对应的内存区域是如何使用,它描述了数据的以下几个方面:
Python
对象)字节顺序是通过对数据类型预先设定 <
或 >
来决定的。 <
意味着小端法(最小值存储在最小的地址,即低位组放在最前面)。>
意味着大端法(最重要的字节存储在最小的地址,即高位组放在最前面)。
dtype
对象是使用以下语法构造的:
numpy.dtype(object, align, copy)
# 参数说明
object - 要转换为的数据类型对象
align - 如果为true,填充字段使其类似C的结构体。
copy - 复制dtype对象,如果为false,则是对内置数据类型对象的引用
# 例子1
import numpy as np
# 使用标量类型
dt1 = np.dtype(np.int32)
# int8, int16, int32, int64四种数据类型可以使用字符串'i1', 'i2','i4','i8'代替
dt2 = np.dtype('i4')
# 字节顺序标注
dt3 = np.dtype(')
print(dt1)
print(dt2)
print(dt4)
# 输出结果
int32
int32
int32
下面实例展示结构化数据类型的使用,类型字段和对应的实际类型将被创建。
import numpy as np
# 例子1
# 首先创建结构化数据类型
dt = np.dtype([('age',np.int8)])
print(dt)
# 输出结果
[('age', 'i1')]
# 例子2
# 将数据类型应用于ndarray对象
dt = np.dtype([('age',np.int8)])
a = np.array([(10,),(20,),(30,)], dtype = dt)
print(a)
# 输出结果
[(10,) (20,) (30,)]
# 例子3
# 类型字段名可以用于存取实际的age列
dt = np.dtype([('age',np.int8)])
a = np.array([(10,),(20,),(30,)], dtype = dt)
print(a['age'])
# 输出结果
[10 20 30]
下面的示例定义一个结构化数据类型student,包含字符串字段name,整数字段age,及浮点字段marks,并将这个dtype应用到ndarray对象。
import numpy as np
# 例子1
student = np.dtype([('name','S20'), ('age', 'i1'), ('marks', 'f4')])
print(student)
# 输出结果
[('name', 'S20'), ('age', 'i1'), ('marks', 'f4')]
# 例子2
a = np.array([('abc', 21, 50),('xyz', 18, 75)], dtype = student)
print(a)
print(a[0])
# 输出结果
[(b'abc', 21, 50.) (b'xyz', 18, 75.)]
(b'abc', 21, 50.)
每个内建类型都有一个唯一定义它的字符代码,如下:
字符 | 对应类型 |
---|---|
b | 布尔型 |
i | (有符号) 整型 |
u | 无符号整型 integer |
f | 浮点型 |
c | 复数浮点型 |
m | timedelta(时间间隔) |
M | datetime(日期时间) |
O | (Python) 对象 |
S,a | (byte-)字符串 |
U | Unicode |
V | 原始数据 (void) |
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 as np
# ndarray.ndim用于返回数组的维数,等于秩。
a = np.arange(24)
print(a.ndim) # a 现只有一个维度
# 现在调整其大小
b = a.reshape(2,4,3) # b 现在拥有三个维度
print(b.ndim)
# 输出结果
1
3
ndarray.shape
表示数组的维度,返回一个元组,这个元组的长度就是维度的数目,即ndim
属性(秩)。比如,一个二维数组,其维度表示"行数"和"列数"。
ndarray.shape
也可以用于调整数组大小。NumPy
也提供了reshape()
函数来调整数组大小。
ndarray.size
数组元素的总个数,相当于 .shape
中n*m的值。
import numpy as np
# 例子1
a = np.array([[1,2,3],[4,5,6]])
print(a.shape)
b = np.array([[1,2,3],[4,5,6]])
b.shape = (3,2)
print(b)
# 输出结果
(2, 3)
[[1 2]
[3 4]
[5 6]]
# 例子2
c = np.array([[1,2,3],[4,5,6]])
d = c.reshape(3,2)
e = np.size(c)
print(d)
# 输出结果
[[1 2]
[3 4]
[5 6]]
6
ndarray.itemsize
以字节的形式返回数组中每一个元素的大小。
例如,一个元素类型为float64
的数组itemsize
属性值为 8(float64
占用64个bits(位),每个字节(Byte)长度为8,所以64/8,占用8个字节),又如,一个元素类型为complex32
的数组item属性为4(32/8)。
import numpy as np
# 数组的dtype为int8(一个字节)
x = np.array([1,2,3,4,5], dtype = np.int8)
print(x.itemsize)
# 数组的dtype现在为float64(八个字节)
y = np.array([1,2,3,4,5], dtype = np.float64)
print(y.itemsize)
# 输出结果
1
8
ndarray.flags
返回ndarray对象的内存信息,包含以下属性:
属性 | 描述 |
---|---|
C_CONTIGUOUS (C) |
数据是在一个单一的C 风格的连续段中 |
F_CONTIGUOUS (F) |
数据是在一个单一的Fortran 风格的连续段中 |
OWNDATA (O) |
数组拥有它所使用的内存或从另一个对象中借用它 |
WRITEABLE (W) |
数据区域可以被写入,将该值设置为False ,则数据为只读 |
ALIGNED (A) |
数据和所有元素都适当地对齐到硬件上 |
UPDATEIFCOPY (U) |
这个数组是其它数组的一个副本,当这个数组被释放时,原数组的内容将被更新 |
import numpy as np
x = np.array([1,2,3,4,5])
print(x.flags)
# 输出结果
C_CONTIGUOUS : True
F_CONTIGUOUS : True
OWNDATA : True
WRITEABLE : True
ALIGNED : True
WRITEBACKIFCOPY : False
UPDATEIFCOPY : False
ndarray.reshape()
通常返回的是非拷贝副本,即改变返回后数组的元素,原数组对应元素的值也会改变。
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
b = a.reshape((6,))
print(a)
print(b)
print("*"*20)
b[0] = 168
print(b)
print(a)
# 输出结果
[[1 2 3]
[4 5 6]]
[1 2 3 4 5 6]
********************
[168 2 3 4 5 6]
[[168 2 3]
[ 4 5 6]]
(1)整数和切片索引
ndarray
对象的内容可以通过索引或切片来访问和修改,与Python
中list
的切片操作一样。
ndarray
数组可以基于0-n
的下标进行索引,切片对象可以通过内置的slice
函数,并设置start, stop及step参数进行,从原数组中切割出一个新数组。
import numpy as np
a = np.arange(10)
# 内置的slice函数
# 从索引2开始到索引7停止,间隔为2
s = slice(2,7,2)
print(a[s])
# 从索引2开始到索引7停止,间隔为2
b = a[2:7:2]
print(b)
# 输出结果
[2 4 6]
[2 4 6]
冒号:
的解释:如果只放置一个参数,如[2]
,将返回与该索引相对应的单个元素。如果为[2:]
,表示从该索引开始以后的所有项都将被提取。如果使用了两个参数,如[2:7]
,那么则提取两个索引(不包括停止索引)之间的项。
import numpy as np
a = np.arange(10) # [0 1 2 3 4 5 6 7 8 9]
b = a[5]
c = a[2:]
d = a[2:5]
print(a)
print(b)
print(c)
print(d)
# 输出结果
[0 1 2 3 4 5 6 7 8 9]
5
[2 3 4 5 6 7 8 9]
[2 3 4]
多维数组同样适用上述索引提取方法。
切片还可以包括省略号…
,来使选择元组的长度与数组的维度相同。 如果在行位置使用省略号,它将返回包含行中元素的ndarray。
import numpy as np
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
print(a)
# 从某个索引处开始切割
print(a[1:])
print(a[...,1]) # 第2列元素
print(a[1,...]) # 第2行元素
print(a[...,1:]) # 第2列及剩下的所有元素
# 输出结果
[[1 2 3]
[3 4 5]
[4 5 6]]
[[3 4 5]
[4 5 6]]
[2 4 5]
[3 4 5]
[[2 3]
[4 5]
[5 6]]
np.s_[:]
的用法,可以参考Python中内置的slice
函数,并设置start, stop及step参数。Out[23]:np.s_[:] Out[23]:slice(None, None, None)
(2)高级索引
# 整数数组索引
import numpy as np
# 获取数组中(0,0),(1,1)和(2,0)位置处的元素。
a = np.array([[1,2], [3,4], [5,6]])
b = a[[0,1,2],[0,1,0]]
print(b)
# 输出结果
[1 4 5]
#**********************************
c = np.array([[0,1,2],[3,4,5],[6,7,8],[9,10,11]])
print(c)
rows = np.array([[0,0],[3,3]])
cols = np.array([[0,2],[0,2]])
d = c[rows,cols]
print(d)
# 输出结果
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]
[[ 0 2]
[ 9 11]]
#**********************************
# 借助切片:或…与索引数组组合。如下面例子:
e = np.array([[1,2,3],[4,5,6],[7,8,9]])
f = e[1:3,1:3]
g = e[1:3,[1,2]]
h = e[...,1:]
print(e)
print(f)
print(g)
print(h)
# 输出结果
[[1 2 3]
[4 5 6]
[7 8 9]]
[[5 6]
[8 9]]
[[5 6]
[8 9]]
[[2 3]
[5 6]
[8 9]]
布尔索引通过布尔运算(如:比较运算符)来获取符合指定条件的元素的数组。
import numpy as np
x = np.array([[0,1,2],[3,4,5],[6,7,8],[9,10,11]])
print(x)
# 现在我们会打印出大于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]
#**********************************
# 使用了~(取补运算符)来过滤NaN
a = np.array([np.nan,1,2,np.nan,3,4,5])
print(a[np.isnan(a)])
print(a[~np.isnan(a)])
# 输出结果
[1. 2. 3. 4. 5.]
#**********************************
# 从数组中过滤掉非复数元素
a = np.array([1,2+6j,5,3.5+5j])
print(a[np.iscomplex(a)])
# 输出结果
[2.+6.j 3.5+5.j]
花式索引指的是利用整数数组进行索引。花式索引根据索引数组的值作为目标数组的某个轴的下标来取值。
对于使用一维整型数组作为索引,如果目标是一维数组,那么索引的结果就是对应位置的元素;如果目标是二维数组,那么就是对应下标的行。
花式索引跟切片不一样,它总是将数据复制到新数组中;
传入多个索引数组(要使用np.ix_
)。np.ix_
函数就是输入两个数组,产生笛卡尔积的映射关系。
笛卡尔乘积是指在数学中,两个集合 X 和 Y 的笛卡尔积(Cartesian product),又称直积,表示为 X×Y,第一个对象是X的成员而第二个对象是 Y 的所有可能有序对的其中一个成员。
import numpy as np
# 一维数组只有一个轴 axis = 0,所以一维数组就在 axis = 0 这个轴上取值:
a = np.arange(1,10)
print(a)
# 一维数组读取指定下标对应的元素
print("-------读取下标对应的元素-------")
b = a[[0,6]] # 使用花式索引
print(b)
print(b[0])
print(b[1])
# 输出结果
[1 2 3 4 5 6 7 8 9]
-------读取下标对应的元素-------
[1 7]
1
7
#**********************************
# 二维数组
c = np.arange(32).reshape((8,4))
print(c)
# 二维数组读取指定下标对应的行,输出下表为4,2,1,7对应的行
print(c[[4,2,1,7]])
# 传入倒序索引数组
print(c[[-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]]
[[16 17 18 19]
[ 8 9 10 11]
[ 4 5 6 7]
[28 29 30 31]]
[[16 17 18 19]
[24 25 26 27]
[28 29 30 31]
[ 4 5 6 7]]
#**********************************
# 传入多个索引数组(要使用np.ix_),笛卡尔积
# 例如 A={a,b}, B={0,1,2},则:
# A×B={(a,0),(a,1),(a,2),(b,0),(b,1),(b,2)}
# B×A={(0,a),(0,b),(1,a),(1,b),(2,a),(2,b)}
d = np.arange(32).reshape((8,4))
print(d)
print(d[np.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]]
广播(Broadcast)是numpy对不同形状(shape)的数组进行数值计算的方式, 对数组的算术运算通常在相应的元素上进行。如果两个数组a和b形状相同,即满足a.shape == b.shape,那么a*b的结果就是a与b数组对应位相乘。这要求维数相同,且各维度的长度相同。
import numpy as np
a = np.array([1,2,3,4])
b = np.array([10,20,30,40])
c = a * b
print(c)
# 当运算中的2个数组的形状不同时,numpy将自动触发广播机制
d = np.array([[0,0,0],
[10,10,10],
[20,20,20],
[30,30,30]])
e = np.array([0,1,2])
print(d + e)
# 4x3的二维数组与长为3的一维数组相加,等效于把数组b在二维上重复4次再运算:
f = np.array([[0,0,0],
[10,10,10],
[20,20,20],
[30,30,30]])
g = np.array([1,2,3])
gg = np.tile(g,(4,1)) #重复b的各个维度
print(gg)
print(f+gg)
# 输出结果
[10 40 90 160]
[[ 0 1 2]
[10 11 12]
[20 21 22]
[30 31 32]]
[[1 2 3]
[1 2 3]
[1 2 3]
[1 2 3]]
[[ 1 2 3]
[11 12 13]
[21 22 23]
[31 32 33]]
广播的规则:
**简单理解:**对两个数组,分别比较他们的每一个维度(若其中一个数组没有当前维度则忽略),满足:
若条件不满足,抛出 “ValueError: frames are not aligned” 异常。
NumPy
迭代器对象numpy.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=", ")
print('\n')
# 输出结果
原始数组是:
[[0 1 2]
[3 4 5]]
迭代输出元素:
0, 1, 2, 3, 4, 5,
以上实例不是使用标准C或者Fortran顺序,选择的顺序是和数组内存布局一致的,这样做是为了提升访问的效率,默认是行序优先(row-major order,或者说是 C-order)。这反映了默认情况下只需访问每个元素,而无需考虑其特定顺序。a
和a.T
的遍历顺序是一样的,也就是他们在内存中的存储顺序也是一样的,但是a.T.copy(order = 'C')
的遍历结果是不同的,那是因为它和前两种的存储方式是不一样的,默认是按行访问。
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,
(1)控制遍历顺序
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,
可以通过显式设置,来强制nditer对象使用某种顺序:
import numpy as np
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=", ")
# 输出结果
原始数组是:
[[ 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,
(2)修改数组中元素的值
nditer
对象有另一个可选参数op_flags
。 默认情况下,nditer
将视待迭代遍历的数组为只读对象(read-only),为了在遍历数组的同时,实现对数组元素值得修改,必须指定readwrite
或者writeonly
的模式。
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[...]是修改原numpy元素,x只是个拷贝。
x[...]=2*x
print('修改后的数组是:')
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]]
(3)使用外部循环
nditer
类的构造器拥有flags参数,它可以接受下列值:
参数 | 描述 |
---|---|
c_index |
可以跟踪C顺序的索引 |
f_index |
可以跟踪Fortran顺序的索引 |
multi_index |
每次迭代可以跟踪一种索引类型 |
external_loop |
给出的值是具有多个值的一维数组,而不是零维数组 |
# 迭代器遍历对应于每列,并组合为一维数组
# 当数组的order与在循环中指定的order顺序不同时,打印为多个一维数组,当相同时,是整个一个一维数组。
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print('原始数组是:')
print(a)
print('\n')
print('修改后的数组(F风格)是:')
for x in np.nditer(a, flags = ['external_loop'], order = 'F'):
print(x, end=", ")
print('\n')
print('修改后的数组(C风格)是:')
for y in np.nditer(a, flags = ['external_loop'], order = 'C'):
print(y, end=", ")
# 输出结果
原始数组是:
[[ 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],
修改后的数组(C风格)是:
[ 0 5 10 15 20 25 30 35 40 45 50 55],
(4)广播迭代
如果两个数组是可广播的,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=", ")
# 输出结果
第一个数组为:
[[ 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,
Numpy
中包含了一些函数用于处理数组,大概可分为以下几类:
函数 | 描述 |
---|---|
reshape |
不改变数据的条件下修改形状 |
flat |
数组元素迭代器 |
flatten |
返回一份数组拷贝,对拷贝所做的修改不会影响原始数组 |
ravel |
返回展开数组 |
函数 | 描述 |
---|---|
transpose |
对换数组的维度 |
ndarray.T |
和 self.transpose() 相同 |
rollaxis |
向后滚动指定的轴 |
swapaxes |
对换数组的两个轴 |
函数 | 描述 |
---|---|
broadcast |
产生模仿广播的对象 |
broadcast_to |
将数组广播到新形状 |
expand_dims |
扩展数组的形状 |
squeeze |
从数组的形状中删除一维条目 |
函数 | 描述 |
---|---|
concatenate |
连接沿现有轴的数组序列 |
stack |
沿着新的轴加入一系列数组。 |
hstack |
水平堆叠序列中的数组(列方向) |
vstack |
竖直堆叠序列中的数组(行方向) |
函数 | 描述 |
---|---|
split |
将一个数组分割为多个子数组 |
hsplit |
将一个数组水平分割为多个子数组(按列) |
vsplit |
将一个数组垂直分割为多个子数组(按行) |
函数 | 描述 |
---|---|
resize |
返回指定形状的新数组 |
append |
将值添加到数组末尾 |
insert |
沿指定轴将值插入到指定下标之前 |
delete |
删掉某个轴的子数组,并返回删除后的新数组 |
unique |
查找数组内的唯一元素 |
NumPy
"bitwise_" 开头的函数是位运算函数。NumPy
位运算包括以下几个函数:
函数 | 描述 |
---|---|
bitwise_and |
对数组元素执行位与操作 |
bitwise_or |
对数组元素执行位或操作 |
invert |
按位取反 |
left_shift |
向左移动二进制表示的位,相当于右侧附加相等数量的0 |
right_shift |
向右移动二进制表示的位,相当于左侧附加相等数量的0 |
bitwise_and()
函数对数组中整数的二进制形式执行位与运算。
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
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
invert()
函数对数组中整数进行位取反运算,即0变成1,1变成0。对于有符号整数,取该二进制数的补码,然后 +1。二进制数,最高位为0表示正数,最高位为1表示负数。
import numpy as np
print('13的位反转,其中ndarray的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的位反转,其中ndarray的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('\n')
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
以下函数用于对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'],[' xyz']))
print('\n')
print('连接示例:')
print(np.char.add(['hello', 'hi'],[' abc', ' xyz']))
# 输出结果
连接两个字符串:
['hello xyz']
连接示例:
['hello abc' 'hi xyz']
numpy.char.multiply()
函数执行多重连接。
import numpy as np
print(np.char.multiply('Runoob ',3))
# 输出结果
Runoob Runoob Runoob
numpy.char.center()
函数用于将字符串居中,并使用指定字符在左侧和右侧进行填充。
import numpy as np
# np.char.center(str , width,fillchar) :
# str: 字符串,width: 长度,fillchar: 填充字符
print(np.char.center('Runoob', 20,fillchar = '*'))
# 输出结果
*******Runoob*******
numpy.char.capitalize()
函数将字符串的第一个字母转换为大写。
import numpy as np
print(np.char.capitalize('runoob'))
# 输出结果
Runoob
numpy.char.title()
函数将字符串的每个单词的第一个字母转换为大写。
import numpy as np
print(np.char.title('i like runoob'))
# 输出结果
I Like Runoob
numpy.char.lower()
函数对数组的每个元素转换为小写。它对每个元素调用str.lower。
import numpy as np
#操作数组
print(np.char.lower(['RUNOOB','GOOGLE']))
# 操作字符串
print(np.char.lower('RUNOOB'))
# 输出结果
['runoob' 'google']
runoob
numpy.char.upper()
函数对数组的每个元素转换为大写。它对每个元素调用 str.upper。
import numpy as np
#操作数组
print(np.char.upper(['runoob','google']))
# 操作字符串
print(np.char.upper('runoob'))
# 输出结果
['RUNOOB' 'GOOGLE']
RUNOOB
numpy.char.split()
通过指定分隔符对字符串进行分割,并返回数组。默认情况下,分隔符为空格。
import numpy as np
# 分隔符默认为空格
print(np.char.split('i like runoob?'))
# 分隔符为.
print(np.char.split('www.runoob.com', sep = '.'))
# 输出结果
['i', 'like', 'runoob?']
['www', 'runoob', 'com']
numpy.char.splitlines()
函数以换行符作为分隔符来分割字符串,并返回数组。
import numpy as np
# \n,\r,\r\n 都可用作换行符。
# 换行符\n
print(np.char.splitlines('i\nlike runoob?'))
print(np.char.splitlines('i\rlike runoob?'))
# 输出结果
['i', 'like runoob?']
['i', 'like runoob?']
numpy.char.strip()
函数用于移除开头或结尾处的特定字符。
import numpy as np
# 移除字符串头尾的a字符
print(np.char.strip('ashok arunooba','a'))
# 移除数组元素头尾的a字符
print(np.char.strip(['arunooba','admin','java'],'a'))
# 输出结果
shok arunoob
['runoob' 'dmin' 'jav']
numpy.char.join()
函数通过指定分隔符来连接数组中的元素或字符串
import numpy as np
# 操作字符串
print(np.char.join(':','runoob'))
# 指定多个分隔符操作数组元素
print(np.char.join([':','-'],['runoob','google']))
# 输出结果
r:u:n:o:o:b
['r:u:n:o:o:b' 'g-o-o-g-l-e']
numpy.char.replace()
函数使用新字符串替换字符串中的所有子字符串。
import numpy as np
print(np.char.replace('i like runoob', 'oo', 'cc'))
# 输出结果
i like runccb
numpy.char.encode()
函数对数组中的每个元素调用str.encode
函数。 默认编码是utf-8,可以使用标准Python库中的编解码器。
import numpy as np
a = np.char.encode('runoob', 'cp500')
print(a)
# 输出结果
b'\x99\xa4\x95\x96\x96\x82'
numpy.char.decode()
函数对编码的元素进行str.decode()
解码。
import numpy as np
a = np.char.encode('runoob', 'cp500')
print(a)
print(np.char.decode(a,'cp500'))
# 输出结果
b'\x99\xa4\x95\x96\x96\x82'
runoob
NumPy
包含大量的各种数学运算的函数,包括三角函数,算术运算的函数,复数处理函数等。
(1)三角函数
NumPy提供了标准的三角函数:sin()、cos()、tan()。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))
# 输出结果
含有正弦值的数组:
[0. 0.5 0.70710678 0.8660254 1. ]
计算角度的反正弦,返回值以弧度为单位:
[0. 0.52359878 0.78539816 1.04719755 1.57079633]
通过转化为角度制来检查结果:
[ 0. 30. 45. 60. 90.]
(2)舍入函数
numpy.around()
函数返回指定数字的四舍五入值。
numpy.around(a,decimals)
参数说明:
a: 数组
decimals: 舍入的小数位数。默认值为0。如果为负,整数将四舍五入到小数点左侧的位置。例如decimals为-1,代表舍入到十位,13舍入为10,16舍入为20
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()
返回小于或者等于指定表达式的最大整数,即向下取整。
numpy.ceil()
返回大于或者等于指定表达式的最小整数,即向上取整。
NumPy
算术函数包含简单的加减乘除: add(),subtract(),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('我们的数组是:')
print(a)
print('\n')
print('调用 reciprocal 函数:')
print(np.reciprocal(a))
# 输出结果
我们的数组是:
[0.25 1.33 1. 100.]
调用 reciprocal 函数:
[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('\n')
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('第一个数组:')
print(a)
print('\n')
print('第二个数组:')
print(b)
print('\n')
print('调用 mod() 函数:')
print(np.mod(a,b))
print('\n')
print('调用 remainder() 函数:')
print(np.remainder(a,b))
# 输出结果
第一个数组:
[10 20 30]
第二个数组:
[3 5 7]
调用mod()函数:
[1 0 2]
调用remainder()函数:
[1 0 2]
NumPy
提供了很多统计函数,用于从数组中查找最小元素,最大元素,百分位标准差和方差等。 函数说明如下:
numpy.amin()
用于计算数组中的元素沿指定轴的最小值。
numpy.amax()
用于计算数组中的元素沿指定轴的最大值。
import numpy as np
a = np.array([[3,7,5],[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('\n')
print('调用amax()函数:')
print(np.amax(a))
print('\n')
print('再次调用amax()函数:')
print(np.amax(a, axis = 0))
# 输出结果
我们的数组是:
[[3 7 5]
[8 4 3]
[2 4 9]]
调用amin()函数:
[3 3 2]
再次调用amin()函数:
[2 4 3]
调用amax()函数:
9
再次调用amax()函数:
[8 7 9]
numpy.ptp()
函数计算数组中元素最大值与最小值的差(最大值 - 最小值)。
import numpy as np
a = np.array([[3,7,5],[8,4,3],[2,4,9]])
print('我们的数组是:')
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 7 5]
[8 4 3]
[2 4 9]]
调用ptp()函数:
7
沿轴1调用ptp()函数:
[4 5 7]
沿轴0调用ptp()函数:
[6 3 6]
百分位数是统计中使用的度量,表示小于这个值的观察值的百分比。 函数numpy.percentile()
接受以下参数。
numpy.percentile(a, q, axis)
参数说明:
a: 输入数组
q: 要计算的百分位数,在0~100之间
axis: 沿着它计算百分位数的轴
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))
# 输出结果
我们的数组是:
[[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.6666666666666665
沿轴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 = sqrt(mean((x-x.mean())**2))
import numpy as np
print(np.std([1,2,3,4]))
# 输出结果
1.118033988749895
统计中的方差(样本方差)是每个样本值与全体样本值的平均数之差的平方值的平均数,即mean((x-x.mean())**2)
。换句话说,标准差是方差的平方根。
import numpy as np
print(np.var([1,2,3,4]))
# 输出结果
1.25
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 = dt)
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
# 传入np.lexsort的是一个tuple,排序时首先排nm,顺序为:amar、anil、raju、ravi。综上排序结果为[3 1 0 2]。
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.']
函数 | 描述 |
---|---|
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
# 复数排序
print(np.sort_complex([5,3,6,2,1]))
print(np.sort_complex([1+2j, 2-1j, 3-2j, 3-3j, 3+5j]))
# 输出结果
[1.+0.j 2.+0.j 3.+0.j 5.+0.j 6.+0.j]
[1.+2.j 2.-1.j 3.-3.j 3.-2.j 3.+5.j]
# partition()分区排序:
a = np.array([3, 4, 2, 1])
# 将数组a中所有元素(包括重复元素)从小到大排列,3表示的是排序数组索引为3的数字,比该数字小的排在该数字前面,比该数字大的排在该数字的后面
print(np.partition(a, 3))
# 小于1的在前面,大于3的在后面,1和3之间的在中间
print(np.partition(a,(1,3)))
# 输出结果
[2 1 3 4]
[1 2 3 4]
arr = np.array([46, 57, 23, 39, 1, 10, 0, 120])
# 找到数组的第3小(index=2)的值和第2大(index=-2)的值
print(arr[np.argpartition(arr, 2)[2]])
print(arr[np.argpartition(arr, -2)[-2]])
# 同时找到第3和第4小的值。注意这里,用[2,3]同时将第3和第4小的排序好,然后可以分别通过下标[2]和[3]取得。
print(arr[np.argpartition(arr,[2,3])[2]])
print(arr[np.argpartition(arr,[2,3])[3]])
# 输出结果
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()
函数返回输入数组中非零元素的索引。
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], dtype=int64), array([0, 1, 1, 2, 0, 2], dtype=int64))
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], dtype=int64), array([1, 2, 0, 1, 2], dtype=int64))
使用这些索引来获取满足条件的元素:
[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.ndarray.byteswap()
函数将ndarray
中每个元素中的字节进行大小端转换。
import numpy as np
import numpy as np
a = np.array([1, 256, 8755], dtype = np.int16)
print('我们的数组是:')
print(a)
print('以十六进制表示内存中的数据:')
print(map(hex,a))
print(list(map(hex, a)))
# byteswap()函数通过传入true来原地交换
print('调用 byteswap() 函数:')
print(a.byteswap(True))
print('十六进制形式:')
print (map(hex,a))
print(list(map(hex, a)))
# 我们可以看到字节已经交换了
# 输出结果
我们的数组是:
[ 1 256 8755]
以十六进制表示内存中的数据:
<map object at 0x00000229347A3D88>
['0x1', '0x100', '0x2233']
调用 byteswap() 函数:
[ 256 1 13090]
十六进制形式:
<map object at 0x00000229347A3608>
['0x100', '0x1', '0x3322']
副本是一个数据的完整的拷贝,如果我们对副本进行修改,它不会影响到原始数据,物理内存不在同一位置。
视图是数据的一个别称或引用,通过该别称或引用亦便可访问、操作原有数据,但原有数据不会产生拷贝。如果我们对视图进行修改,它会影响到原始数据,物理内存在同一位置。
副本一般发生在:
视图一般发生在:
(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)
# 输出结果
我们的数组是:
[0 1 2 3 4 5]
调用id()函数:
2375996889168
a赋值给b:
[0 1 2 3 4 5]
b拥有相同id():
2375996889168
修改 b 的形状:
[[0 1]
[2 3]
[4 5]]
a的形状也修改了:
[[0 1]
[2 3]
[4 5]]
(2)视图或浅拷贝
ndarray.view()
方会创建一个新的数组对象,该方法创建的新数组的维数变化不会改变原始数据的维数。
import numpy as np
# 最开始 a 是个 3X2 的数组
a = np.arange(6).reshape(3,2)
print('数组a:')
print(a)
print('创建a的视图:')
b = a.view()
print(b)
print('两个数组的id()不同:')
print('a的id():')
print(id(a))
print('b的id():' )
print(id(b))
# 修改b的形状,并不会修改a
b.shape = 2,3
print('b的形状:')
print(b)
print('a的形状:')
print(a)
# 输出结果
数组a:
[[0 1]
[2 3]
[4 5]]
创建a的视图:
[[0 1]
[2 3]
[4 5]]
两个数组的id()不同:
a的id():
2375996990448
b的id():
2375996617872
b的形状:
[[0 1 2]
[3 4 5]]
a的形状:
[[0 1]
[2 3]
[4 5]]
使用切片创建视图修改数据会影响到原始数组,变量a,b都是arr的一部分视图,对视图的修改会直接反映到原数据中。但是我们观察a,b的id,他们是不同的,也就是说,视图虽然指向原数据,但是他们和赋值引用还是有区别的。
import numpy as np
arr = np.arange(12)
print('我们的数组:')
print(arr)
print('创建切片:')
a=arr[3:]
b=arr[3:]
a[1]=123
b[2]=234
print(arr)
print(id(a),id(b),id(arr[3:]))
# 输出结果
我们的数组:
[ 0 1 2 3 4 5 6 7 8 9 10 11]
创建切片:
[ 0 1 2 3 123 234 6 7 8 9 10 11]
2375996635536 2375996634816 2375996921616
(3)副本或深拷贝
ndarray.copy()
函数创建一个副本。 对副本数据进行修改,不会影响到原始数据,它们物理内存不在同一位置。
import numpy as np
a = np.array([[10,10], [2,3], [4,5]])
print('数组a:')
print(a)
print('创建a的深层副本:')
b = a.copy()
print('数组 b:')
print(b)
# b与a不共享任何内容
print('我们能够写入b来写入a吗?')
print(b is a)
print('修改b的内容:')
b[0,0] = 100
print('修改后的数组b:')
print(b)
print('a保持不变:')
print(a)
# 输出结果
数组a:
[[10 10]
[ 2 3]
[ 4 5]]
创建a的深层副本:
数组 b:
[[10 10]
[ 2 3]
[ 4 5]]
我们能够写入b来写入a吗?
False
修改b的内容:
修改后的数组b:
[[100 10]
[ 2 3]
[ 4 5]]
a保持不变:
[[10 10]
[ 2 3]
[ 4 5]]
NumPy
中包含了一个矩阵库numpy.matlib
,该模块中的函数返回一个矩阵,而不是ndarray
对象。一个m×n
的矩阵是一个由m行(row)n列(column)元素排列成的矩形阵列。矩阵里的元素可以是数字、符号或数学式。
(1)转置矩阵
NumPy
中除了可以使用numpy.transpose
函数来对换数组的维度,还可以使用 T 属性。
import numpy as np
a = np.arange(12).reshape(3,4)
print('原数组:')
print(a)
print('\n')
print('转置数组:')
print(a.T)
# 输出结果
原数组:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
转置数组:
[[ 0 4 8]
[ 1 5 9]
[ 2 6 10]
[ 3 7 11]]
(2)matlib.empty()
matlib.empty()
函数返回一个新的矩阵,语法格式为:
numpy.matlib.empty(shape, dtype, order)
参数说明:
shape: 定义新矩阵形状的整数或整数元组
Dtype: 可选,数据类型
order: C(行序优先) 或者 F(列序优先)
import numpy as np
print(np.matlib.empty((2,2)))
# 填充为随机数据
# 输出结果
[[1.36008890e-311 1.69168361e-301]
[3.42821614e-210 7.46699190e-301]]
(3)numpy.matlib.zeros()
numpy.matlib.zeros()
函数创建一个以0填充的矩阵。
import numpy as np
print(np.matlib.zeros((2,2)))
# 输出结果
[[0. 0.]
[0. 0.]]
(4)numpy.matlib.ones()
numpy.matlib.ones()
函数创建一个以1填充的矩阵。
import numpy as np
print(np.matlib.ones((2,2)))
# 输出结果
[[1. 1.]
[1. 1.]]
(5)numpy.matlib.eye()
numpy.matlib.eye()
函数返回一个矩阵,对角线元素为1,其他位置为零。
numpy.matlib.eye(n, M,k, dtype)
参数说明:
n: 返回矩阵的行数
M: 返回矩阵的列数,默认为n
k: 对角线的索引
dtype: 数据类型
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.]]
(6)numpy.matlib.identity()
numpy.matlib.identity()
函数返回给定大小的单位矩阵。单位矩阵是个方阵,从左上角到右下角的对角线(称为主对角线)上的元素均为1,除此以外全都为0。
import numpy as np
# 大小为 5,类型位浮点型
print(np.matlib.identity(5, dtype=float))
# 输出结果
[[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.]]
(7)numpy.matlib.rand()
numpy.matlib.rand()
函数创建一个给定大小的矩阵,数据是随机填充的。
import numpy as np
print(np.matlib.rand(3,3))
# 输出结果
[[0.85907694 0.10033233 0.90102019]
[0.60724393 0.67443377 0.19654135]
[0.1626346 0.4910893 0.11768052]]
矩阵总是二维的,而ndarray是一个n维数组。 两个对象都是可互换的。
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)
# 输出结果
[[1 2]
[3 4]]
[[1 2]
[3 4]]
[[1 2]
[3 4]]
NumPy
提供了线性代数函数库linalg,该库包含了线性代数所需的所有功能,可以看看下面的说明:
函数 | 描述 |
---|---|
dot |
两个数组的点积,即元素对应相乘 |
vdot |
两个向量的点积 |
inner |
两个数组的内积 |
matmul |
两个数组的矩阵积 |
determinant |
数组的行列式 |
solve |
求解线性矩阵方程 |
inv |
计算矩阵的乘法逆矩阵 |
Numpy
可以读写磁盘上的文本数据或二进制数据。
NumPy
为ndarray
对象引入了一个简单的文件格式:npy。
npy
文件用于存储重建ndarray
所需的数据、图形、dtype和其他信息。
常用的IO
函数有:
load()
和save()
函数是读写文件数组数据的两个主要函数,默认情况下,数组是以未压缩的原始二进制格式保存在扩展名为.npy
的文件中。savez()
函数用于将多个数组写入文件,默认情况,数组是以未压缩的原始二进制格式保存在扩展名为.npz
的文件中。loadtxt()
和savetxt()
函数处理正常的文本文件(.txt
等)(1)numpy.save()
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)
# 可以看出文件是乱码的,因为它们是Numpy专用的二进制格式后的数据。
# 我们可以使用load()函数来读取数据就可以正常显示了
b = np.load('outfile.npy')
print(b)
# 输出结果
[1 2 3 4 5]
(2)np.savez()
numpy.savez()
函数将多个数组保存到以.npz
为扩展名的文件中。
numpy.savez(file, *args, **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("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
# 输出结果
['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]
(3)np.savetxt()
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
# arr.shape # (a,b)
# arr.reshape(m,-1) # 改变维度为m行、d列(-1表示列数自动计算,d=a*b/m)
# arr.reshape(-1,m) # 改变维度为d行、m列(-1表示行数自动计算,d=a*b/m)
a = np.arange(0,10,0.5).reshape(4,-1)
print(a)
np.savetxt("out.txt",a,fmt="%d",delimiter=",") # 改为保存为整数,以逗号分隔
b = np.loadtxt("out.txt",delimiter=",") # load 时也要指定为逗号分隔
print(b)
# 输出结果
[[0. 0.5 1. 1.5 2. ]
[2.5 3. 3.5 4. 4.5]
[5. 5.5 6. 6.5 7. ]
[7.5 8. 8.5 9. 9.5]]
[[0. 0. 1. 1. 2.]
[2. 3. 3. 4. 4.]
[5. 5. 6. 6. 7.]
[7. 8. 8. 9. 9.]]
Matplotlib
是Python
的绘图库。 它可与NumPy
一起使用,提供了一种有效的MatLab
开源替代方案。它也可以和图形工具包一起使用,如PyQt
和wxPython
。
参考资料:菜鸟教程
笔者不才,请多交流!!!
欢迎大家关注预览我的博客Blog:HeartLoveLife
能力有限,敬请谅解!!