NumPy 是一个 Python 包。 它代表 “Numeric Python”。 它是一个由多维数组对象和用于处理数组的例程集合组成的库。
Numeric,即 NumPy 的前身,是由 Jim Hugunin 开发的。 也开发了另一个包 Numarray ,它拥有一些额外的功能。 2005年,Travis Oliphant 通过将 Numarray 的功能集成到 Numeric 包中来创建 NumPy 包。 这个开源项目有很多贡献者。
NumPy 中定义的最重要的对象是称为 ndarray 的 N 维数组类型。 它描述相同类型的元素集合。 可以使用基于零的索引访问集合中的项目。
ndarray中的每个元素在内存中使用相同大小的块。 ndarray中的每个元素是数据类型对象的对象(称为 dtype)。
从ndarray对象提取的任何元素(通过切片)由一个数组标量类型的 Python 对象表示。 下图显示了ndarray,数据类型对象(dtype)和数组标量类型之间的关系。
它从任何暴露数组接口的对象,或从返回数组的任何方法创建一个ndarray。
numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
import numpy as np
a = np.array([[1, 2], [3, 4]])
print(a)
结果:
[[1 2]
[3 4]]
numpy 支持的数据类型比 Python 内置的类型要多很多,基本上可以和 C 语言的数据类型对应上,其中部分类型对应为 Python 内置的类型。下表列举了常用 NumPy 基本类型。
dtype 对象是使用以下语法构造的:
numpy.dtype(object, align, copy)
示例:
import numpy as np
# 使用标量类型
dt = np.dtype(np.int32)
print(dt)
结果:
int32
NumPy 数组的维数称为秩(rank),秩就是轴的数量,即数组的维度,一维数组的秩为 1,二维数组的秩为 2,以此类推。
在 NumPy中,每一个线性的数组称为是一个轴(axis),也就是维度(dimensions)。比如说,二维数组相当于是两个一维数组,其中第一个一维数组中每个元素又是一个一维数组。所以一维数组就是 NumPy 中的轴(axis),第一个轴相当于是底层数组,第二个轴是底层数组里的数组。而轴的数量——秩,就是数组的维数。
很多时候可以声明 axis。axis=0,表示沿着第 0 轴进行操作,即对每一列进行操作;axis=1,表示沿着第1轴进行操作,即对每一行进行操作。
ndarray 数组除了可以使用底层 ndarray 构造器来创建外,也可以通过以下几种方式来创建
numpy.empty(shape, dtype = float, order = 'C')
numpy.zeros(shape, dtype = float, order = 'C')
numpy.ones(shape, dtype = None, order = 'C')
numpy.asarray 类似 numpy.array,但 numpy.asarray 参数只有三个,比 numpy.array 少两个。
numpy.asarray(a, dtype = None, order = None)
numpy.frombuffer 用于实现动态数组。
numpy.frombuffer 接受 buffer 输入参数,以流的形式读入转化成 ndarray 对象。
numpy.frombuffer(buffer, dtype = float, count = -1, offset = 0)
numpy.fromiter 方法从可迭代对象中建立 ndarray 对象,返回一维数组。
numpy.fromiter(iterable, dtype, count=-1)
numpy 包中的使用 arange 函数创建数值范围并返回 ndarray 对象,根据 start 与 stop 指定的范围以及 step 设定的步长,生成一个 ndarray。
numpy.arange(start, stop, step, dtype)
numpy.linspace 函数用于创建一个一维数组,数组是一个等差数列构成的,
np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
numpy.logspace 函数用于创建一个于等比数列,base 参数意思是取对数的时候 log 的下标。
np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
ndarray 数组可以基于 0 - n 的下标进行索引,切片对象可以通过内置的 slice 函数,并设置 start, stop 及 step 参数进行,从原数组中切割出一个新数组。
示例:
import numpy as np
a = np.arange(10)
b = a[2:7:2] # 从索引 2 开始到索引 7 停止,间隔为 2
c = np.array([[1,2,3],[3,4,5],[4,5,6]])
print('b:',b)
print('c:',c)
结果:
b: [2 4 6]
c:[[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列元素
结果:
[2 4 5]
NumPy 比一般的 Python 序列提供更多的索引方式。
除了之前看到的用整数和切片的索引外,数组可以由整数数组索引、布尔索引及花式索引。
NumPy 中的高级索引指的是使用整数数组、布尔数组或者其他序列来访问数组的元素。相比于基本索引,高级索引可以访问到数组中的任意元素,并且可以用来对数组进行复杂的操作和修改。
整数数组索引是指使用一个数组来访问另一个数组的元素。这个数组中的每个元素都是目标数组中某个维度上的索引值。
示例:
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
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]
花式索引指的是利用整数数组进行索引。
花式索引根据索引数组的值作为目标数组的某个轴的下标来取值。
对于使用一维整型数组作为索引,如果目标是一维数组,那么索引的结果就是对应位置的元素,如果目标是二维数组,那么就是对应下标的行。
花式索引跟切片不一样,它总是将数据复制到新数组中。
广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式, 对数组的算术运算通常在相应的元素上进行。
如果两个数组 a 和 b 形状相同,即满足 a.shape == b.shape,那么 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([0,1,2])
print(a + b)
结果:
[[ 0 1 2]
[10 11 12]
[20 21 22]
[30 31 32]]
对两个数组,分别比较他们的每一个维度(若其中一个数组没有当前维度则忽略),满足:
若条件不满足,抛出 “ValueError: frames are not aligned” 异常。
NumPy 迭代器对象 numpy.nditer 提供了一种灵活访问一个或者多个数组元素的方式。
迭代器最基本的任务的可以完成对数组元素的访问。
示例:
import numpy as np
a = np.arange(6).reshape(2,3)
print ('迭代输出元素:')
for x in np.nditer(a):
print (x, end=", " )
结果:
迭代输出元素:
0, 1, 2, 3, 4, 5,
示例:
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
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 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 对象有另一个可选参数 op_flags。 默认情况下,nditer 将视待迭代遍历的数组为只读对象(read-only),为了在遍历数组的同时,实现对数组元素值得修改,必须指定 readwrite 或者 writeonly 的模式。
示例:
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
for x in np.nditer(a, op_flags=['readwrite']):
x[...]=2*x
print ('修改后的数组是:')
print (a)
结果:
修改后的数组是:
[[ 0 10 20 30]
[ 40 50 60 70]
[ 80 90 100 110]]
nditer 类的构造器拥有 flags 参数,它可以接受下列值:
迭代器遍历对应于每列,并组合为一维数组。
示例:
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print ('修改后的数组是:')
for x in np.nditer(a, flags = ['external_loop'], order = 'F'):
print (x, end=", " )
结果:
修改后的数组是:
[ 0 20 40], [ 5 25 45], [10 30 50], [15 35 55],
如果两个数组是可广播的,nditer 组合对象能够同时迭代它们。 假设数组 a 的维度为 3X4,数组 b 的维度为 1X4 ,则使用以下迭代器(数组 b 被广播到 a 的大小)。
示例:
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
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=", " )
结果:
第二个数组为:
[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 中包含了一些函数用于处理数组,大概可分为以下几类:
numpy.transpose 函数用于对换数组的维度,格式如下:
numpy.transpose(arr, axes)
参数说明:
示例:
import numpy as np
a = np.arange(12).reshape(3,4)
print ('对换数组:')
print (np.transpose(a))
结果:
对换数组:
[[ 0 4 8]
[ 1 5 9]
[ 2 6 10]
[ 3 7 11]]
numpy.rollaxis 函数向后滚动特定的轴到一个特定位置,格式如下:
numpy.rollaxis(arr, axis, start)
参数说明:
示例:
import numpy as np
# 创建了三维的 ndarray
a = np.arange(8).reshape(2,2,2)
print ('获取数组中一个值:')
print(np.where(a==6))
print(a[1,1,0]) # 为 6
print ('\n')
# 将轴 2 滚动到轴 0(宽度到深度)
print ('调用 rollaxis 函数:')
b = np.rollaxis(a,2,0)
print (b)
# 查看元素 a[1,1,0],即 6 的坐标,变成 [0, 1, 1]
# 最后一个 0 移动到最前面
print(np.where(b==6))
print ('\n')
# 将轴 2 滚动到轴 1:(宽度到高度)
print ('调用 rollaxis 函数:')
c = np.rollaxis(a,2,1)
print (c)
# 查看元素 a[1,1,0],即 6 的坐标,变成 [1, 0, 1]
# 最后的 0 和 它前面的 1 对换位置
print(np.where(c==6))
print ('\n')
结果:
获取数组中一个值:
(array([1]), array([1]), array([0]))
6
调用 rollaxis 函数:
[[[0 2]
[4 6]]
[[1 3]
[5 7]]]
(array([0]), array([1]), array([1]))
调用 rollaxis 函数:
[[[0 2]
[1 3]]
[[4 6]
[5 7]]]
(array([1]), array([0]), array([1]))
numpy.swapaxes 函数用于交换数组的两个轴,格式如下:
numpy.swapaxes(arr, axis1, axis2)
示例:
import numpy as np
# 创建了三维的 ndarray
a = np.arange(8).reshape(2,2,2)
# 现在交换轴 0(深度方向)到轴 2(宽度方向)
print ('调用 swapaxes 函数后的数组:')
print (np.swapaxes(a, 2, 0))
结果:
调用 swapaxes 函数后的数组:
[[[0 4]
[2 6]]
[[1 5]
[3 7]]]
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 函数将数组广播到新形状。它在原始数组上返回只读视图。 它通常不连续。 如果新形状不符合 NumPy 的广播规则,该函数可能会抛出ValueError。
numpy.broadcast_to(array, shape, subok)
示例:
import numpy as np
a = np.arange(4).reshape(1,4)
print ('调用 broadcast_to 函数之后:')
print (np.broadcast_to(a,(4,4)))
结果:
调用 broadcast_to 函数之后:
[[0 1 2 3]
[0 1 2 3]
[0 1 2 3]
[0 1 2 3]]
numpy.expand_dims 函数通过在指定位置插入新的轴来扩展数组形状,函数格式如下:
numpy.expand_dims(arr, axis)
参数说明:
示例:
import numpy as np
x = np.array(([1,2],[3,4]))
y = np.expand_dims(x, axis = 0)
print ('数组 y:')
print (y)
print ('\n')
print ('数组 x 和 y 的形状:')
print (x.shape, y.shape)
print ('\n')
# 在位置 1 插入轴
y = np.expand_dims(x, axis = 1)
print ('在位置 1 插入轴之后的数组 y:')
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)
结果:
数组 y:
[[[1 2]
[3 4]]]
数组 x 和 y 的形状:
(2, 2) (1, 2, 2)
在位置 1 插入轴之后的数组 y:
[[[1 2]]
[[3 4]]]
x.ndim 和 y.ndim:
2 3
x.shape 和 y.shape:
(2, 2) (2, 1, 2)
numpy.squeeze 函数从给定数组的形状中删除一维的条目,函数格式如下:
numpy.squeeze(arr, axis)
参数说明:
示例:
import numpy as np
x = np.arange(9).reshape(1,3,3)
y = np.squeeze(x)
print ('数组 y:')
print (y)
print ('\n')
print ('数组 x 和 y 的形状:')
print (x.shape, y.shape)
结果:
数组 y:
[[0 1 2]
[3 4 5]
[6 7 8]]
数组 x 和 y 的形状:
(1, 3, 3) (3, 3)
numpy.concatenate 函数用于沿指定轴连接相同形状的两个或多个数组,格式如下:
numpy.concatenate((a1, a2, ...), axis)
参数说明:
示例:
import numpy as np
a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])
# 两个数组的维度相同
print ('沿轴 0 连接两个数组:')
print (np.concatenate((a,b)))
print ('\n')
print ('沿轴 1 连接两个数组:')
print (np.concatenate((a,b),axis = 1))
结果:
沿轴 0 连接两个数组:
[[1 2]
[3 4]
[5 6]
[7 8]]
沿轴 1 连接两个数组:
[[1 2 5 6]
[3 4 7 8]]
numpy.stack 函数用于沿新轴连接数组序列,格式如下:
numpy.stack(arrays, axis)
参数说明:
示例:
import numpy as np
a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])
print ('沿轴 0 堆叠两个数组:')
print (np.stack((a,b),0))
print ('\n')
print ('沿轴 1 堆叠两个数组:')
print (np.stack((a,b),1))
结果:
沿轴 0 堆叠两个数组:
[[[1 2]
[3 4]]
[[5 6]
[7 8]]]
沿轴 1 堆叠两个数组:
[[[1 2]
[5 6]]
[[3 4]
[7 8]]]
numpy.hstack 是 numpy.stack 函数的变体,它通过水平堆叠来生成数组。
示例:
import numpy as np
a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])
print ('水平堆叠:')
c = np.hstack((a,b))
print (c)
print ('\n')
结果:
水平堆叠:
[[1 2 5 6]
[3 4 7 8]]
numpy.vstack 是 numpy.stack 函数的变体,它通过垂直堆叠来生成数组。
示例:
import numpy as np
a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])
print ('竖直堆叠:')
c = np.vstack((a,b))
print (c)
结果:
import numpy as np
a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])
print ('竖直堆叠:')
c = np.vstack((a,b))
print (c)
numpy.split 函数沿特定的轴将数组分割为子数组,格式如下:
numpy.split(ary, indices_or_sections, axis)
参数说明:
示例:
import numpy as np
a = np.arange(9)
print ('将数组分为三个大小相等的子数组:')
b = np.split(a,3)
print (b)
print ('\n')
print ('将数组在一维数组中表明的位置分割:')
b = np.split(a,[4,7])
print (b)
结果:
将数组分为三个大小相等的子数组:
[array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]
将数组在一维数组中表明的位置分割:
[array([0, 1, 2, 3]), array([4, 5, 6]), array([7, 8])]
numpy.hsplit 函数用于水平分割数组,通过指定要返回的相同形状的数组数量来拆分原数组。
示例:
import numpy as np
harr = np.floor(10 * np.random.random((2, 6)))
print ('拆分后:')
print(np.hsplit(harr, 3))
结果:
拆分后:
[array([[4., 7.],
[6., 3.]]), array([[6., 3.],
[6., 7.]]), array([[2., 6.],
[9., 7.]])]
numpy.vsplit 沿着垂直轴分割,其分割方式与hsplit用法相同。
示例:
import numpy as np
a = np.arange(16).reshape(4,4)
print ('竖直分割:')
b = np.vsplit(a,2)
print (b)
结果:
竖直分割:
[array([[0, 1, 2, 3],
[4, 5, 6, 7]]), array([[ 8, 9, 10, 11],
[12, 13, 14, 15]])]
numpy.resize 函数返回指定大小的新数组。
如果新数组大小大于原始大小,则包含原始数组中的元素的副本。
numpy.resize(arr, shape)
参数说明:
示例:
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
print ('第一个数组的形状:')
print (a.shape)
print ('\n')
b = np.resize(a, (3,2))
print ('第二个数组的形状:')
print (b.shape)
print ('\n')
# 要注意 a 的第一行在 b 中重复出现,因为尺寸变大了
print ('修改第二个数组的大小:')
b = np.resize(a,(3,3))
print (b)
结果:
第一个数组的形状:
(2, 3)
第二个数组的形状:
(3, 2)
修改第二个数组的大小:
[[1 2 3]
[4 5 6]
[1 2 3]]
numpy.append 函数在数组的末尾添加值。 追加操作会分配整个数组,并把原来的数组复制到新数组中。 此外,输入数组的维度必须匹配否则将生成ValueError。
append 函数返回的始终是一个一维数组。
numpy.append(arr, values, axis=None)
参数说明:
示例:
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
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 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]]
numpy.insert 函数在给定索引之前,沿给定轴在输入数组中插入值。
如果值的类型转换为要插入,则它与输入数组不同。 插入没有原地的,函数会返回一个新数组。 此外,如果未提供轴,则输入数组会被展开。
numpy.insert(arr, obj, values, axis)
参数说明:
示例:
import numpy as np
a = np.array([[1,2],[3,4],[5,6]])
print ('未传递 Axis 参数。 在删除之前输入数组会被展开。')
print (np.insert(a,3,[11,12]))
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))
结果:
未传递 Axis 参数。 在删除之前输入数组会被展开。
[ 1 2 3 11 12 4 5 6]
传递了 Axis 参数。 会广播值数组来配输入数组。
沿轴 0 广播:
[[ 1 2]
[11 11]
[ 3 4]
[ 5 6]]
沿轴 1 广播:
[[ 1 11 2]
[ 3 11 4]
[ 5 11 6]]
numpy.delete 函数返回从输入数组中删除指定子数组的新数组。 与 insert() 函数的情况一样,如果未提供轴参数,则输入数组将展开。
Numpy.delete(arr, obj, axis)
参数说明:
示例:
import numpy as np
a = np.arange(12).reshape(3,4)
print ('未传递 Axis 参数。 在插入之前输入数组会被展开。')
print (np.delete(a,5))
print ('\n')
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]))
结果:
未传递 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)
示例:
import numpy as np
a = np.array([5,2,6,2,7,5,6,8,2,9])
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)
结果:
第一个数组的去重值:
[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 “bitwise_” 开头的函数是位运算函数。
bitwise_and() 函数对数组中整数的二进制形式执行位与运算。
示例:
import numpy as np
a,b = 13,17
print ('13 和 17 的位与:')
print (np.bitwise_and(13, 17))
结果:
13 和 17 的位与:
1
bitwise_or()函数对数组中整数的二进制形式执行位或运算。
示例:
import numpy as np
a,b = 13,17
print ('13 和 17 的位或:')
print (np.bitwise_or(13, 17))
结果:
13 和 17 的位或:
29
invert() 函数对数组中整数进行位取反运算,即 0 变成 1,1 变成 0。
对于有符号整数,取该二进制数的补码,然后 +1。二进制数,最高位为0表示正数,最高位为 1 表示负数。
看看 ~1 的计算步骤:
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。(与left_shift用法相同)
以下函数用于对 dtype 为 numpy.string_ 或 numpy.unicode_ 的数组执行向量化字符串操作。 它们基于 Python 内置库中的标准字符串函数。
numpy.char.add() 函数依次对两个数组的元素进行字符串连接。
numpy.char.multiply() 函数执行多重连接。
numpy.char.center() 函数用于将字符串居中,并使用指定字符在左侧和右侧进行填充。
numpy.char.capitalize() 函数将字符串的第一个字母转换为大写
numpy.char.title() 函数将字符串的每个单词的第一个字母转换为大写
numpy.char.lower() 函数对数组的每个元素转换为小写。它对每个元素调用 str.lower。
numpy.char.upper() 函数对数组的每个元素转换为大写。它对每个元素调用 str.upper。
numpy.char.split() 通过指定分隔符对字符串进行分割,并返回数组。默认情况下,分隔符为空格。
numpy.char.splitlines() 函数以换行符作为分隔符来分割字符串,并返回数组。
numpy.char.strip() 函数用于移除开头或结尾处的特定字符。
numpy.char.join() 函数通过指定分隔符来连接数组中的元素或字符串
numpy.char.replace() 函数使用新字符串替换字符串中的所有子字符串。
numpy.char.encode() 函数对数组中的每个元素调用 str.encode 函数。 默认编码是 utf-8,可以使用标准 Python 库中的编解码器。
numpy.char.decode() 函数对编码的元素进行 str.decode() 解码。
NumPy 包含大量的各种数学运算的函数,包括三角函数,算术运算的函数,复数处理函数等。
NumPy 提供了标准的三角函数:sin()、cos()、tan()。
arcsin,arccos,和 arctan 函数返回给定角度的 sin,cos 和 tan 的反三角函数。
这些函数的结果可以通过 numpy.degrees() 函数将弧度转换为角度。
返回指定数字的四舍五入值。
numpy.around(a,decimals)
参数说明:
numpy.floor() 返回小于或者等于指定表达式的最大整数,即向下取整。
numpy.ceil() 返回大于或者等于指定表达式的最小整数,即向上取整。
NumPy 算术函数包含简单的加减乘除: add(),subtract(),multiply() 和 divide()。
需要注意的是数组必须具有相同的形状或符合数组广播规则。
numpy.reciprocal() 函数返回参数逐元素的倒数。如 1/4 倒数为 4/1。
numpy.power() 函数将第一个输入数组中的元素作为底数,计算它与第二个输入数组中相应元素的幂。
numpy.mod() 计算输入数组中相应元素的相除后的余数。 函数 numpy.remainder() 也产生相同的结果。
NumPy 提供了很多统计函数,用于从数组中查找最小元素,最大元素,百分位标准差和方差等。 函数说明如下:
numpy.amin() 用于计算数组中的元素沿指定轴的最小值。
numpy.amax() 用于计算数组中的元素沿指定轴的最大值。
示例:
import numpy as np
a = np.array([[3,7,5],[8,4,3],[2,4,9]])
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))
结果:
调用 amin() 函数:
[3 3 2]
再次调用 amin() 函数:
[2 4 3]
调用 amax() 函数:
9
再次调用 amax() 函数:
[8 7 9]
numpy.ptp()函数计算数组中元素最大值与最小值的差(最大值 - 最小值)。
百分位数是统计中使用的度量,表示小于这个值的观察值的百分比。 函数numpy.percentile()接受以下参数。
numpy.percentile(a, q, axis)
参数说明:
numpy.median() 函数用于计算数组 a 中元素的中位数(中值)
numpy.mean() 函数返回数组中元素的算术平均值。 如果提供了轴,则沿其计算。
算术平均值是沿轴的元素的总和除以元素的数量。
numpy.average() 函数根据在另一个数组中给出的各自的权重计算数组中元素的加权平均值。
该函数可以接受一个轴参数。 如果没有指定轴,则数组会被展开。
加权平均值即将各数值乘以相应的权数,然后加总求和得到总体值,再除以总的单位数。
考虑数组[1,2,3,4]和相应的权重[4,3,2,1],通过将相应元素的乘积相加,并将和除以权重的和,来计算加权平均值。
加权平均值 = (1*4+2*3+3*2+4*1)/(4+3+2+1)
标准差是一组数据平均值分散程度的一种度量。
标准差是方差的算术平方根。
标准差公式如下:
# std = sqrt(mean((x - x.mean())**2))
import numpy as np
print (np.std([1,2,3,4]))
统计中的方差(样本方差)是每个样本值与全体样本值的平均数之差的平方值的平均数,即 mean((x - x.mean())** 2)。
换句话说,标准差是方差的平方根。
import numpy as np
print (np.var([1,2,3,4]))
NumPy 提供了多种排序的方法。 这些排序函数实现不同的排序算法,每个排序算法的特征在于执行速度,最坏情况性能,所需的工作空间和算法的稳定性。 下表显示了三种排序算法的比较。
numpy.sort() 函数返回输入数组的排序副本。函数格式如下
numpy.sort(a, axis, kind, order)
参数说明:
numpy.argsort() 函数返回的是数组值从小到大的索引值。
numpy.lexsort() 用于对多个序列进行排序。把它想象成对电子表格进行排序,每一列代表一个序列,排序时优先照顾靠后的列。
这里举一个应用场景:小升初考试,重点班录取学生按照总成绩录取。在总成绩相同时,数学成绩高的优先录取,在总成绩和数学成绩都相同时,按照英语成绩录取…… 这里,总成绩排在电子表格的最后一列,数学成绩在倒数第二列,英语成绩在倒数第三列。
numpy.argmax() 和 numpy.argmin()函数分别沿给定轴返回最大和最小元素的索引。
numpy.nonzero() 函数返回输入数组中非零元素的索引。
numpy.where() 函数返回输入数组中满足给定条件的元素的索引。
numpy.extract() 函数根据某个条件从数组中抽取元素,返回满条件的元素。
在几乎所有的机器上,多字节对象都被存储为连续的字节序列。字节顺序,是跨越多字节的程序对象的存储规则。
大端模式:指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;这和我们的阅读习惯一致。
小端模式:指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低。
numpy.ndarray.byteswap() 函数将 ndarray 中每个元素中的字节进行大小端转换。
副本是一个数据的完整的拷贝,如果我们对副本进行修改,它不会影响到原始数据,物理内存不在同一位置。
视图是数据的一个别称或引用,通过该别称或引用亦便可访问、操作原有数据,但原有数据不会产生拷贝。如果我们对视图进行修改,它会影响到原始数据,物理内存在同一位置。
视图一般发生在:
副本一般发生在:
简单的赋值不会创建数组对象的副本。 相反,它使用原始数组的相同**id()**来访问它。 **id()**返回 Python 对象的通用标识符,类似于 C 中的指针。
此外,一个数组的任何变化都反映在另一个数组上。 例如,一个数组的形状改变也会改变另一个数组的形状。
ndarray.view() 方会创建一个新的数组对象,该方法创建的新数组的维数变化不会改变原始数据的维数。
**ndarray.copy()**函数创建一个副本。 对副本数据进行修改,不会影响到原始数据,它们物理内存不在同一位置。
NumPy 中包含了一个矩阵库 numpy.matlib,该模块中的函数返回的是一个矩阵,而不是 ndarray 对象。
一个 的矩阵是一个由行(row)列(column)元素排列成的矩形阵列。
矩阵里的元素可以是数字、符号或数学式。
NumPy 中除了可以使用 numpy.transpose 函数来对换数组的维度,还可以使用 T 属性。
例如有个 m 行 n 列的矩阵,使用 t() 函数就能转换为 n 行 m 列的矩阵。
matlib.empty() 函数返回一个新的矩阵,语法格式为:
numpy.matlib.empty(shape, dtype, order)
参数说明:
numpy.matlib.zeros() 函数创建一个以 0 填充的矩阵。
numpy.matlib.ones()函数创建一个以 1 填充的矩阵。
numpy.matlib.eye() 函数返回一个矩阵,对角线元素为 1,其他位置为零。
numpy.matlib.eye(n, M,k, dtype)
参数说明:
numpy.matlib.identity() 函数返回给定大小的单位矩阵。
单位矩阵是个方阵,从左上角到右下角的对角线(称为主对角线)上的元素均为 1,除此以外全都为 0。
numpy.matlib.rand() 函数创建一个给定大小的矩阵,数据是随机填充的。
NumPy 提供了线性代数函数库 linalg,该库包含了线性代数所需的所有功能,可以看看下面的说明:
numpy.dot() 对于两个一维的数组,计算的是这两个数组对应下标元素的乘积和(数学上称之为向量点积);对于二维数组,计算的是两个数组的矩阵乘积;对于多维数组,它的通用计算公式如下,即结果数组中的每个元素都是:数组a的最后一维上的所有元素与数组b的倒数第二位上的所有元素的乘积和: dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])。
numpy.dot(a, b, out=None)
参数说明:
numpy.vdot() 函数是两个向量的点积。 如果第一个参数是复数,那么它的共轭复数会用于计算。 如果参数是多维数组,它会被展开。
numpy.inner() 函数返回一维数组的向量内积。对于更高的维度,它返回最后一个轴上的和的乘积。
numpy.matmul 函数返回两个数组的矩阵乘积。 虽然它返回二维数组的正常乘积,但如果任一参数的维数大于2,则将其视为存在于最后两个索引的矩阵的栈,并进行相应广播。
另一方面,如果任一参数是一维数组,则通过在其维度上附加 1 来将其提升为矩阵,并在乘法之后被去除。
numpy.linalg.det() 函数计算输入矩阵的行列式。
行列式在线性代数中是非常有用的值。 它从方阵的对角元素计算。 对于 2×2 矩阵,它是左上和右下元素的乘积与其他两个的乘积的差。
换句话说,对于矩阵[[a,b],[c,d]],行列式计算为 ad-bc。 较大的方阵被认为是 2×2 矩阵的组合。
numpy.linalg.solve() 函数给出了矩阵形式的线性方程的解。
numpy.linalg.inv() 函数计算矩阵的乘法逆矩阵。
逆矩阵(inverse matrix):设A是数域上的一个n阶矩阵,若在相同数域上存在另一个n阶矩阵B,使得: AB=BA=E ,则我们称B是A的逆矩阵,而A则被称为可逆矩阵。注:E为单位矩阵。
Numpy 可以读写磁盘上的文本数据或二进制数据。
NumPy 为 ndarray 对象引入了一个简单的文件格式:npy。
npy 文件用于存储重建 ndarray 所需的数据、图形、dtype 和其他信息。
常用的 IO 函数有:
numpy.save() 函数将数组保存到以 .npy 为扩展名的文件中。
numpy.save(file, arr, allow_pickle=True, fix_imports=True)
参数说明:
numpy.savez() 函数将多个数组保存到以 npz 为扩展名的文件中。
numpy.savez(file, *args, **kwds)
参数说明:
savetxt() 函数是以简单的文本文件格式存储数据,对应的使用 loadtxt() 函数来获取数据。
np.loadtxt(FILENAME, dtype=int, delimiter=' ')
np.savetxt(FILENAME, a, fmt="%d", delimiter=",")
参数 delimiter 可以指定各种分隔符、针对特定列的转换器函数、需要跳过的行数等。