简介
NumPy(Numerical Python)是 Python 中用于科学计算的核心库,专注于高效处理多维数组(矩阵)和提供大量数学运算函数,是数据分析、机器学习、科学计算等领域的基础工具。
在NumPy包的核心是ndarray对象。该对象封装了具有同质数据类型的n维数组,并且为了提高性能,许多操作都是通过编译代码执行的。
-
高效的多维数组对象(ndarray)
- 同构数据的多维容器(所有元素类型相同),比 Python 内置的列表(list)运算速度快得多(底层用 C 实现)。
- 支持自定义维度(1D 向量、2D 矩阵、3D 张量等)。
-
丰富的数学运算函数
- 提供矩阵运算(加减乘除、转置、求逆等)、统计分析(均值、方差、求和等)、线性代数、傅里叶变换等功能。
-
广播机制(Broadcasting)
- 允许不同形状的数组之间进行算术运算(自动扩展维度以匹配),简化代码。
-
与其他库的兼容性
是 Pandas、Matplotlib、Scikit-learn 等数据科学库的基础,数据格式可无缝互通。
安装
pip install numpy
广播机制
广播的第一条规则是,如果所有输入数组的维度数量不同,那么会在较小数组的形状前反复添加 “1”,直到所有数组的维度数量相同。
广播的第二条规则确保,在某一特定维度上大小为1的数组,其行为就好像它在该维度上的大小与形状最大的数组相同。对于 “广播” 数组,假定该数组元素在该维度上的值是相同的。
数据类型
要转换数组的类型,请使用.astype()方法
z.astype(np.float64)
数据类型对象
import numpy as np
a= np.dtype(np.int64)
print(a)
# int64
数据类型标识码
| 字符 | 对应类型 |
|---|---|
| b | 代表布尔型 |
| i | 带符号整型 |
| u | 无符号整型 |
| f | 浮点型 |
| c | 复数浮点型 |
| m | 时间间隔(timedelta) |
| M | datatime(日期时间) |
| O | Python对象 |
| S,a | 字节串(S)与字符串(a) |
| U | Unicode |
| V | 原始数据(void) |
数值数据类型
有5种基本数值类型,分别表示布尔值(bool)、整数(int)、无符号整数(uint)、浮点数(float)和complex。
字符串和字节的数据类型
NumPy 还支持存储 Unicode 字符串,通过 numpy.str_ 数据类型(U 字符代码)存储,通过 numpy.bytes_(S 字符代码)存储以空字符结尾的字节序列,以及通过 numpy.void(V 字符代码)存储任意字节序列。
np.array(["hello", "world!"])
ndarray
属性
- data: 包含数组实际元素的缓冲区
- itemsize: 数组中每个元素的字节大小
- dtype:一个描述数组中元素类型的对象
- size:数组元素的总数。这等于shape的元素的乘积。
- shape : 数组的维度。这是一个整数元组,表示数组在每个维度上的大小。
- ndim: 数组的轴(维度)数量。
创建
默认情况下,创建的数组的数据类型为float64,但可以通过关键字参数dtype指定。
arange
import numpy as np
a = np.arange(15).reshape(3, 5)
当使用带有浮点参数的arange时,由于浮点精度有限,通常无法预测得到的元素数量。因此,通常最好使用函数linspace,它接收我们想要的元素数量作为参数,而不是步长。
linspace
np.linspace(0, 2, 9)
array
np.array([1, 2, 3]) # 一维数组
np.array([(1.5, 2, 3), (4, 5, 6)]) # 二维数组
np.array([[1, 2], [3, 4]], dtype=complex) # 指定类型
zeros & ones & empty
np.zeros((3, 4))
np.ones((2, 3, 4), dtype=np.int16)
np.empty((2, 3))
zeros_like & ones_like & empty_like
a = np.arange(10).reshape(2, 5)
b = np.ones_like(a)
eye & diag & vander
np.eye(3) # 三维单位阵
numpy.diag 既可以定义一个主对角线为给定值的二维方阵,也可以在传入二维数组时,返回一个仅包含对角线元素的一维数组。
np.diag([1, 2, 3]) # 主对角线未1,2,3 的方阵
np.diag([1, 2, 3], 1) # 向主对角线右上方偏移1
a = np.array([[1, 2], [3, 4]])
np.diag(a)
vander(x, n) 将范德蒙德矩阵定义为一个二维NumPy数组。范德蒙德矩阵的每一列都是输入的一维数组、列表或元组 x 的降幂,其中最高多项式阶数为 n-1。此数组创建例程在生成线性最小二乘模型时很有用。
np.vander((1, 2, 3, 4), 4)
random
a = np.random.randint((3,4))
indices
numpy.indices 会创建一组数组(堆叠成一个高一维的数组),每个维度对应一个数组,每个数组表示该维度上的变化:
np.indices((3,3))
"""
array([[[0, 0, 0],
[1, 1, 1],
[2, 2, 2]],
[[0, 1, 2],
[0, 1, 2],
[0, 1, 2]]])
"""
从文件读取
np.loadtxt('simple.csv', delimiter = ',', skiprows = 1)
np.fromfunction
def f(x, y):
return 10 * x + y
# 创建一个5*4的数组,x,y 的值是根据当前的行和列的序号,0开始
b = np.fromfunction(f, (5, 4), dtype=int)
array([[ 0, 1, 2, 3],
[10, 11, 12, 13],
[20, 21, 22, 23],
[30, 31, 32, 33],
[40, 41, 42, 43]])
基本运算
a = np.array([20, 30, 40, 50])
b = np.arange(4)
c = a - b
b**2
10 * np.sin(a)
a < 35 # 返回bool
a *= 3 # 就地修改,而不是创建新的
b += a
# 当使用不同类型的数组进行操作时,结果数组的类型对应于更通用或更精确的类型
d = np.linspace(0, 7, 4)
b + d
在NumPy数组中,乘法运算符 * 按元素进行运算。矩阵乘法可以使用 @ 运算符(在Python >=3.5中)或 dot 函数或方法来执行
A = np.array([[1, 1],
[0, 1]])
B = np.array([[2, 0],
[3, 4]])
A * B
A @ B
A.dot(B)
索引 & 切片 & 迭代
如果索引值超出范围,则会引发 IndexError
一维数组
a = np.arange(10)**3
a[2]
a[2:5]
a[:6:2] = 500 # 前6个 每个两个修改值为500
a[::-1] # 翻转
多维数组
b = np.arange(20).reshape(5,4)
b[2, 3] # 第三行,第四列
b[0:5, 1] # 第二列
b[:, 1] # 第二列
b[1:3, :]
b[-1] # 最后一行
...
# 如果 x 是一个具有 5 个轴的数组
x[1, 2, ...] 等效于 x[1, 2, :, :, :]
x[..., 3] 等同于 x[:, :, :, :, 3]
x[4, ..., 5, :] 等同于 x[4, :, :, 5, :]
整数数组索引
x = np.arange(10, 1, -1)
x[np.array([3, 3, 1, 8])]
# 一维度
x = np.array([[1, 2], [3, 4], [5, 6]])
x[[0, 1, 2], [0, 1, 0]] # (0,0), (1,0), (2,0) 的值
# 多维度
rows = np.array([0, 3], dtype=np.intp)
columns = np.array([0, 2], dtype=np.intp)
x[rows[:, np.newaxis], columns] # 获取(0, 0), (0, 2), (3, 0), (3, 2) 的值
# 使用ix_ 可实现类似的效果
x[np.ix_(rows, columns)]
布尔数组索引
x = np.array([[1., 2.], [np.nan, 3.], [np.nan, np.nan]])
x[~np.isnan(x)]
x = np.array([1., -1., -2., 3])
x[x < 0] += 20
x = np.arange(35).reshape(5, 7)
b = x > 20
x[b[:, 5]] # 获取最后两行的值
迭代
对多维数组进行迭代是按照第一轴进行的
for row in b:
print(row)
如果想要对数组中的每个元素执行操作,可以使用 flat 属性,它是一个遍历数组所有元素的 迭代器:
for element in b.flat:
print(element)
形状操作
查看
| 方法 | 描述 |
|---|---|
| ndarray.flags | 有关数组内存布局的信息。 |
| ndarray.shape | 数组维度的元组。 |
| ndarray.strides | 遍历数组时每个维度中的字节元组。 |
| ndarray.ndim | 数组维数。 |
| ndarray.data | Python缓冲区对象指向数组的数据的开头。 |
| ndarray.size | 数组中的元素数。 |
| ndarray.itemsize | 一个数组元素的长度,以字节为单位 |
| ndarray.nbytes | 数组元素消耗的总字节数。 |
| ndarray.base | 如果内存来自其他对象,则为基础对象。 |
ravel
a.ravel() # returns the array, flattened
让多维数组变成一维数组
返回一个连续的扁平数组(即展开的一维数组),与 flatten不同,它返回的是数组视图(修改视图会影响原数组)
不会改变原数组的形状
reshape
不会改变原数组的形状
a.reshape(6, 2) # returns the array with a modified shape
# 如果在重塑操作中某个维度被指定为 -1,则其他维度会自动计算
a.reshape(3, -1)
reshape能够帮助用户把原数组按照新的维度重新排列。在使用时有两种模式,分别为C模式和F模式,分别以逐行和逐列的顺序进行填充读取
a.reshape((4,2), order='C')
a.reshape((4,2), order='F')
.T
不会改变原数组的形状
转置
a.T # returns the array, transposed
base
如果一个ndarray是通过其他ndarray经过某种操作创建出来的,那么其base就会指向最初的源头。
a = np.arange(20)
b = a.reshape(2,5,2)
print(b.base) # [1-20]
strides
ndarray的每一个维度(axis)都有一个strides,表示从数组在某个维度进行遍历的内存偏移量
a = np.arange(24).reshape([2, 3, 4])
print(a.strides) # ==> (48, 16, 4)
flat
返回是一个迭代器,可以用 for 循环遍历其中的每一个元素。
flatten
flatten: 以一维数组的形式返回一份数组的副本,对副本的操作不会影响到原数组。
broadcast
broadcast 生成一个模拟广播的对象。
broadcast_to
broadcast_to 将数组广播为新的形状。
expand_dims
expand_dims(arr, axis) 扩展数组的形状。
squeeze
squeeze(arr, axis)
- 删除数组中维度为 1 的项
- 指定的维度值必须为 1 ,否则将会报错,若为 None,则删除数组维度中所有为 1 的项。
trnaspose
transpose(,axes=())
改变了数组的维度(axis)排列顺序。
transpose操作只是改变了strides的顺序,没有重新排列内存中的数据。
transpose([0, 1, 2]): 将数组的维度值进行对换,比如二维数组维度(2,4)使用该方法后为(4,2)。
rollaxis
rollaxis(arr. axis, start): 沿着指定的轴向后滚动至规定的位置。
swapaxes
swapaxes(arr. axis1, axis2): 对数组的轴进行对换。
resize
修改数组本身
a.resize((2, 6))
扩维
rows = np.array([0, 3], dtype=np.intp)
rows[:, np.newaxis] # 2, 1
堆叠
vstack & hstack
a = np.floor(10 * rg.random((2, 2)))
b = np.floor(10 * rg.random((2, 2)))
np.vstack((a, b)) # 垂直堆叠,加在行上
np.hstack((a, b)) # 水平堆叠,加在列上
对于超过二维的数组,hstack 沿着其第二轴堆叠,vstack 沿着其第一轴堆叠.
hstack & column_stack
函数column_stack 将一维数组按列堆叠成二维数组。仅对于二维数组,它等同于hstack
np.column_stack((a, b))
a = np.array([4., 2.])
b = np.array([3., 8.])
np.column_stack((a, b))
"""
array([[4., 3.],
[2., 8.]])
"""
np.hstack((a, b))
# array([4., 2., 3., 8.])
concatenate
沿指定轴连接两个或者多个相同形状的数组
numpy.concatenate((a1, a2, ...), axis):
stack 沿着新的轴连接一系列数组
r_ & c_
np.r_[]: 行,上下
np.c_[]: 列, 左右
np.r_[1:4, 0, 4]
a = np.array([[1, 2, 3],[7,8,9]])
b=np.array([[4,5,6],[1,2,3]])
np.c_[a, b]
"""
array([[1, 2, 3, 4, 5, 6],
[7, 8, 9, 1, 2, 3]])
"""
np.r_[a, b]
"""
array([[1, 2, 3],
[7, 8, 9],
[4, 5, 6],
[1, 2, 3]])
"""
分割
split
numpy.split(ary, indices_or_sections, axis)`将一个数组分割为多个子数组
-
indices_or_sections:
-
若是一个整数,代表用该整数平均切分,
-
若是一个数组,则代表沿轴切分的位置(左开右闭)
-
-
axis:默认为0,表示横向切分;为1时表示纵向切分
hsplit
使用 hsplit,你可以沿水平轴拆分数组,既可以指定要返回的形状相同的数组数量,也可以指定拆分应在哪些列之后进行
a = np.floor(10 * rg.random((2, 12)))
np.hsplit(a, 3) # 拆分成3个
np.hsplit(a, (3, 4)) # 拆分成3个,第3列分割,第4列分割
vsplit
vsplit 沿垂直轴拆分
array_split
array_split 允许指定沿哪个轴拆分。
复制
完全不复制
简单赋值不会复制对象或其数据。
a = np.floor(10 * rg.random((2, 12)))
b = a
b is a # True # a and b are two names for the same ndarray object
# 引用传递参数
def f(x):
print(id(x))
id(a)
f(a)
视图或浅拷贝
不同的数组对象可以共享相同的数据。view 方法创建一个新的数组对象,该对象查看相同的数据。
c = a.view()
c is a # False
c.base is a # True
c.flags.owndata # False
c = c.reshape((2, 6))
a.shape # 未改变
c[0, 4] = 1234
a # a的值修改
切片数组会返回其视图
s = a[:, 1:3]
s[:] = 10
a
深拷贝
copy方法会对数组及其数据进行完整的复制。
d = a.copy()
d is a # False
d[0, 0] = 9999
a # 未修改
通用函数
NumPy提供了常见的数学函数, 这些函数对数组进行逐元素操作,并输出一个数组。
a = np.arange(3)
np.exp(a)
np.sqrt(a)
一元

二元

统计
b = np.arange(12).reshape(3, 4)
b.sum() # sum all element
b.sum(axis=0) # sum of each column
b.min(axis=1) # min of each row
b.cumsum(axis=1) # cumulative sum along each row
b.argmin() # 返回最小值索引
b.argmax()
数组的集合操作
- unique(x):唯一值
- intersect1d(x, y): 交集
- union1d(x, y) : 并集
- in1d(x, y):查看x的元素是否包含在y中,返回一个布尔数组
- setdiff1d(x, y):差集
- setxor1d(x, y): 异或
随机数

choice
choice可以从给定的列表中,以一定概率和方式抽取结果,当不指定概率时为均匀采样,默认抽取方式为有放回抽样:
my_list = ['a', 'b', 'c', 'd']
np.random.choice(my_list, 2, replace=False, p=[0.1, 0.7, 0.1 ,0.1])
"""
array(['b', 'a'], dtype='<U1')
"""
np.random.choice(my_list, (3,3))
"""
array([['c', 'b', 'd'],
['d', 'a', 'd'],
['a', 'c', 'd']], dtype='<U1')
"""
permutation
当返回的元素个数与原列表相同时,不放回抽样等价于使用permutation函数,即打散原列表:
np.random.permutation(my_list)
线型代数
numpy.linalg

6849

被折叠的 条评论
为什么被折叠?



