文章目录
1 简介
NumPy 是一个运行速度非常快的数学库,主要用于数组计算,包含:
- 一个强大的N维数组对象 ndarray
- 广播功能函数
- 整合 C/C++/Fortran 代码的工具
- 线性代数、傅里叶变换、随机数生成等功能
2 Ndarray 对象
NumPy 最重要的一个特点是其 N 维数组对象 ndarray。
- 内部结构:
- 指针,指向数据
- 数据类型dtype,描述在数组中的固定大小值的格子
- 表示数组形状shape的元组
- 跨度元组stride
- 创建:
numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
含义:
object
数组或嵌套的数列
dtype
数组元素的数据类型,可选
copy
对象是否需要复制,可选
order
创建数组的样式,C为行方向,F为列方向,A为任意方向(默认)
subok
默认返回一个与基类类型一致的数组
ndmin
指定生成数组的最小维度
例子:
import numpy as np
a = np.array([1, 2, 3,4,5], ndmin = 2)
print (a)
>>>[[1, 2, 3, 4, 5]]
a = np.array([1, 2, 3], dtype = complex)
print (a)
>>>[ 1.+0.j, 2.+0.j, 3.+0.j]
3 数据类型
- 数据类型对象dtype
包括:
-数据的类型(整数,浮点数或者 Python 对象)
-数据的大小(例如, 整数使用多少个字节存储)
-数据的字节顺序(小端法或大端法) - dtype构造:
numpy.dtype(object, align, copy)
含义:
object
- 要转换为的数据类型对象
align
- 如果为 true,填充字段使其类似 C 的结构体。
copy
- 复制 dtype 对象 ,如果为 false,则是对内置数据类型对象的引用 - 例子:
注:字节顺序是通过对数据类型预先设定"<“或”>“来决定的。”<“意味着小端法(最小值存储在最小的地址,即低位组放在最前面)。”>"意味着大端法(最重要的字节存储在最小的地址,即高位组放在最前面
int8, int16, int32, int64 四种数据类型可以使用字符串 ‘i1’, ‘i2’,‘i4’,‘i8’ 代替
dt = np.dtype(‘i4’)
# 首先创建结构化数据类型
import numpy as np
dt = np.dtype([('age',np.int8)])
print(dt)
>>>[('age', 'i1')]
a = np.array([(10,),(20,),(30,)], dtype = dt)
print(a)
>>>[(10,) (20,) (30,)]
print(a['age'])
>>>[10 20 30]
#定义一个结构化数据类型 student,包含字符串字段 name,整数字段 age,及浮点字段 marks,并将这个 dtype 应用到 ndarray 对象
import numpy as np
student = np.dtype([('name','S20'), ('age', 'i1'), ('marks', 'f4')])
a = np.array([('abc', 21, 50),('xyz', 18, 75)], dtype = student)
print(a)
>>>[('abc', 21, 50.0), ('xyz', 18, 75.0)]
4 数组属性
- 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 | 包含实际数组元素的缓冲区,由于一般通过数组的索引获取元素,所以通常不需要使用这个属性。 |
- 调整数组大小:
reshape 函数
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
b = a.reshape(3,2)
print (b)
>>>
[[1, 2]
[3, 4]
[5, 6]]
5 创建数组
除了np.ndarray
外创建数组的其他方式:
numpy.empty
创建一个指定形状(shape)、数据类型(dtype)且未初始化的数组
numpy.empty(shape, dtype = float, order = 'C')
shape 数组形状
dtype 数据类型,可选
order 有"C"和"F"两个选项,分别代表,行优先和列优先,在计算机内存中的存储元素的顺序
注意 − 数组元素为随机值,因为它们未初始化。numpy.zeros
创建指定大小的数组,数组元素以 0 来填充
numpy.zeros(shape, dtype = float, order = 'C')
z = np.zeros((2,2), dtype = [('x', 'i4'), ('y', 'i4')])
print(z)
>>>
[[(0, 0) (0, 0)]
[(0, 0) (0, 0)]]
numpy.ones
numpy.ones(shape, dtype = None, order = 'C')
6 从已有的数组创建数组
- numpy.asarray
numpy.asarray(a, dtype = None, order = None)
a——任意形式的输入参数,可以是,列表, 列表的元组, 元组, 元组的元组, 元组的列表,多维数组
例子:
#将列表转换为 ndarray:
import numpy as np
x = [1,2,3]
a = np.asarray(x)
print (a)
>>>[1 2 3]
#将元组列表转换为 ndarray:
x = [(1,2,3),(4,5)]
a = np.asarray(x)
print (a)
>>>[(1, 2, 3) (4, 5)]
numpy.frombuffer
numpy.frombuffer 用于实现动态数组。numpy.frombuffer 接受 buffer 输入参数,以流的形式读入转化成 ndarray 对象。
numpy.frombuffer(buffer, dtype = float, count = -1, offset = 0)
注:buffer 是字符串的时候,Python3 默认 str 是 Unicode 类型,所以要转成 bytestring 在原 str 前加上 b,如下
例子:
import numpy as np
s = b'Hello World'
a = np.frombuffer(s, 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']
s = 'Hello World'
a = np.frombuffer(s, dtype = 'S1')
print (a)
>>>['H' 'e' 'l' 'l' 'o' ' ' 'W' 'o' 'r' 'l' 'd']
numpy.fromiter
numpy.fromiter 方法从可迭代对象中建立 ndarray 对象,返回一维数组。
numpy.fromiter(iterable, dtype, count=-1)
7 从数值范围创建数组
numpy.arange
numpy.arange(start, stop, step, dtype)
例子:
import numpy as np
x = np.arange(5)
print (x)
>>>[0 1 2 3 4]
x = np.arange(10,20,2)
print (x)
>>>[10 12 14 16 18]
numpy.linspace
用于创建一个一维数组,数组是一个等差数列构成
np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
例子:
import numpy as np
#设置起始点为 1 ,终止点为 10,数列个数为 10
a = np.linspace(1,10,10)
print(a)
>>>[ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]
#将 endpoint 设为 false,不包含终止值,
a = np.linspace(10, 20, 5, endpoint = False)
print(a)
>>>[10. 12. 14. 16. 18.]
#结合reshape函数
b =np.linspace(1,10,10).reshape([10,1])
print(b)
>>>[[ 1.]
[ 2.]
[ 3.]
[ 4.]
[ 5.]
[ 6.]
[ 7.]
[ 8.]
[ 9.]
[10.]]
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)
print (a)
>>>[ 10. 12.91549665 16.68100537 21.5443469 27.82559402
35.93813664 46.41588834 59.94842503 77.42636827 100. ]
8 切片和索引
ndarray 数组可以基于 0 - n 的下标进行索引,切片对象可以通过内置的 slice
函数,并设置 start, stop 及 step 参数进行,从原数组中切割出一个新数组。
a = np.arange(10)
s = slice(2,7,2) # 从索引 2 开始到索引 7 停止,间隔为2
print (a[s])
>>>[2 4 6]
slice(start,stop,step)
&a[start:stop:step]
冒号 : 的解释:如果只放置一个参数,如 [2],将返回与该索引相对应的单个元素。如果为 [2:],表示从该索引开始以后的所有项都将被提取。如果使用了两个参数,如 [2:7],那么则提取两个索引(不包括停止索引)之间的项
- 多维数组索引提取:
import numpy as np
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
print(a)
# 从某个索引处开始切割
print(a[1:])
>>>
[[1 2 3]
[3 4 5]
[4 5 6]]
[[3 4 5]
[4 5 6]]
切片还可以包括省略号 …,来使选择元组的长度与数组的维度相同。 如果在行位置使用省略号,它将返回包含行中元素的 ndarray
import numpy as np
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
print (a[...,1]) # 第2列元素
print (a[1,...]) # 第2行元素
print (a[...,1:]) # 第2列及剩下列的所有元素
>>>
[2 4 5]
[3 4 5]
[[2 3]
[4 5]
[5 6]]
8 高级索引
除了之前看到的用整数和切片的索引外,数组可以由整数数组索引、布尔索引及花式索引。
- 整数数组索引
#以下实例获取数组中(0,0),(1,1)和(2,0)位置处的元素。[[行],[列]]
import numpy as np
x = np.array([[1, 2], [3, 4], [5, 6]])
y = x[[0,1,2], [0,1,0]]
print (y)
>>>[1 4 5]
借助切片 : 或 … 与索引数组组合。如下面例子:
import numpy as np
a = np.array([[1,2,3], [4,5,6],[7,8,9]])
b = a[1:3, 1:3]#取2~3行,2~3列
c = a[1:3,[1,2]]#取2~3行,2、3列
d = a[...,1:]#取1及以后的所有列
print(b)
print(c)
print(d)
- 布尔索引
布尔索引通过布尔运算(如:比较运算符)来获取符合指定条件的元素的数组
import numpy as np
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
# 现在我们会打印出大于 5 的元素
print ('大于 5 的元素是:')
print (x[x > 5])
>>>
大于 5 的元素是:
[ 6 7 8 9 10 11]
可以使用 ~
(取补运算符)来过滤 NaN
import numpy as np
a = np.array([np.nan, 1,2,np.nan,3,4,5])
print (a[~np.isnan(a)])
>>>[ 1. 2. 3. 4. 5.]
同理,可以过滤非复数元素:
import numpy as np
a = np.array([1, 2+6j, 5, 3.5+5j])
print (a[np.iscomplex(a)])
>>>[2.0+6.j 3.5+5.j]
- 花式索引
9 广播(Broadcast)
广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式
如果a、b数组形状相同,a*b
的结果就是 a 与 b 数组对应位相乘
如果运算中的 2 个数组的形状不同,numpy 将自动触发广播机制:
import numpy as np
a = np.array([[ 0, 0, 0],
[10,10,10],
[20,20,20],
[30,30,30]])
b = np.array([1,2,3])
print(a + b)
>>>
[[ 1 2 3]
[11 12 13]
[21 22 23]
[31 32 33]]
广播的规则:
- 让所有输入数组都向其中形状最长的数组看齐,形状中不足的部分都通过在前面加 1 补齐。
- 输出数组的形状是输入数组形状的各个维度上的最大值。
- 如果输入数组的某个维度和输出数组的对应维度的长度相同或者其长度为 1 时,这个数组能够用来计算,否则出错。
- 当输入数组的某个维度的长度为 1 时,沿着此维度运算时都用此维度上的第一组值。
简单理解:
对两个数组,分别比较他们的每一个维度(若其中一个数组没有当前维度则忽略),满足:
- 数组拥有相同形状。
- 当前维度的值相等。
- 当前维度的值有一个是 1。
若条件不满足,抛出 “ValueError: frames are not aligned” 异常。
10 迭代数组
numpy. nditer
例子:
import numpy as np
a = np.arange(6).reshape(2,3)
print ('迭代输出元素:')
for x in np.nditer(a):
print (x, end=", " )
print ('\n')
>>>
迭代输出元素:
0, 1, 2, 3, 4, 5,
11 *数组操作
数组操作类型:
- 修改数组形状
- 翻转数组
- 修改数组维度
- 连接数组
- 分割数组
- 数组元素的添加与删除
- 修改数组形状
- *
numpy.reshape(arr, newshape, order='C')
在不改变数据的条件下修改形状 numpy.ndarray.flat
数组元素迭代器,例子:
- *
import numpy as np
a = np.arange(9).reshape(3,3)
#对数组中每个元素都进行处理,可以使用flat属性,该属性是一个数组元素迭代器:
print ('迭代后的数组:')
for element in a.flat:#a = np.arange(9).reshape(3,3)
print (element)
>>>
迭代后的数组:
0
1
2
3
4
5
6
7
8
ndarray.flatten(order='C')
返回一份数组拷贝,对拷贝所做的修改不会影响原始数组,例子:
import numpy as np
a = np.arange(8).reshape(2,4)
print ('原数组:')
print (a)
print ('\n')
print ('以 F 风格顺序调用 ravel 函数之后:')
print (a.ravel(order = 'F'))
>>>
原数组:
[[0 1 2 3]
[4 5 6 7]]
以 F 风格顺序调用 ravel 函数之后:
[0 4 1 5 2 6 3 7]
numpy.ravel(a, order='C')
展平的数组元素,顺序通常是"C风格",返回的是数组视图(view,有点类似 C/C++引用reference的意味),修改会影响原始数组
- 翻转数组
numpy.transpose(arr, axes)
numpy.rollaxis(arr, axis, start)
numpy.swapaxes(arr, axis1, axis2)
- 修改数组维度
numpy.broadcast
import numpy as np
x = np.array([[1], [2], [3]])
y = np.array([4, 5, 6])
# 对 y 广播 x
b = np.broadcast(x,y)
# 它拥有 iterator 属性,基于自身组件的迭代器元组
print ('对 y 广播 x:')
r,c = b.iters
# Python3.x 为 next(context) ,Python2.x 为 context.next()
print (next(r), next(c))
print (next(r), next(c))
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)
>>>
对 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]]
numpy.broadcast_to(array, shape, subok)
numpy.expand_dims(arr, axis)
numpy.squeeze(arr, axis)
- 连接数组
numpy.concatenate((a1, a2, ...), axis)
axisnumpy.stack(arrays, axis)
numpy.hstack()
numpy.vstack()
- 分割数组
numpy.split(ary, indices_or_sections, axis)
numpy.hsplit()
numpy.vsplit()
- 数组元素的添加与删除
numpy.resize(arr, shape)
numpy.append(arr, values, axis=None)
numpy.insert(arr, obj, values, axis)
numpy.delete(arr, obj, axis)
numpy.unique(arr, return_index, return_inverse, return_counts)
12 位运算
13 字符串函数
函数 | 描述 |
---|---|
add() | 对两个数组的逐个字符串元素进行连接 |
multiply() | 返回按元素多重连接后的字符串 |
center() | 居中字符串 |
capitalize() | 将字符串第一个字母转换为大写 |
title() | 将字符串的每个单词的第一个字母转换为大写 |
lower() | 数组元素转换为小写 |
upper() | 数组元素转换为大写 |
split() | 指定分隔符对字符串进行分割,并返回数组列表 |
splitlines() | 返回元素中的行列表,以换行符分割 |
strip() | 移除元素开头或者结尾处的特定字符 |
join() | 通过指定分隔符来连接数组中的元素 |
replace() | 使用新字符串替换字符串中的所有子字符串 |
decode() | 数组元素依次调用str.decode |
encode() | 数组元素依次调用str.encode |
14 数学函数
- 三角函数
sin()、cos()、tan()
- 舍入函数
numpy.around(a,decimals)
返回指定数字的四舍五入值
numpy.floor()
返回小于或者等于指定表达式的最大整数,即向下取整
numpy.ceil()
返回大于或者等于指定表达式的最小整数,即向上取整
15 算术函数
- 加减乘除
add(),subtract(),multiply() 和 divide()
- 倒数
numpy.reciprocal()
函数返回参数逐元素的倒数 - 幂
numpy.power()
函数将第一个输入数组中的元素作为底数,计算它与第二个输入数组中相应元素的幂 - 余数
numpy.mod()
计算输入数组中相应元素的相除后的余数。 函数numpy.remainder()
也产生相同的结果
16 统计函数
- 最值
numpy.amin()
用于计算数组中的元素沿指定轴的最小值。
numpy.amax()
用于计算数组中的元素沿指定轴的最大值。
numpy.ptp()
函数计算数组中元素最大值与最小值的差(最大值 - 最小值) - 百分比
numpy.percentile(a, q, axis)
表示小于这个值的观察值的百分比
q: 要计算的百分位数,在 0 ~ 100 之间
axis: 沿着它计算百分位数的轴 - 中位数
numpy.median()
函数用于计算数组 a 中元素的中位数(中值) - 算术平均
numpy.mean()
函数返回数组中元素的算术平均值。 如果提供了轴,则沿其计算。 - 加权平均
numpy.average()
函数根据在另一个数组中给出的各自的权重计算数组中元素的加权平均值。该函数可以接受一个轴参数。 如果没有指定轴,则数组会被展开。 - 标准差
np.std()
即std = sqrt(mean((x - x.mean())**2))
标准差是方差的算术平方根 - 方差
np.var()
即mean((x - x.mean())** 2)
方差(样本方差)是每个样本值与全体样本值的平均数之差的平方值的平均数