广播(Broadcast)
- 广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式
import numpy as np
# arr位一个3x3的数组,b为一个一维数组
arr = np.arange(9).reshape(3, 3)
b = np.array([1, 2, 3])
print(arr + b)
在进行数组运算时,会触发广播机制,将b数组也广播成一个3x3的数组
b = np.array([[1, 2, 3],
[1, 2, 3],
[1, 2, 3]])
在运算过程中,实际上就是arr数组与广播后的b数组进行运算
广播的规则:
- 让所有输入数组都向其中形状最长的数组看齐,形状中不足的部分都通过在前面加 1 补齐。
- 输出数组的形状是输入数组形状的各个维度上的最大值。
- 如果输入数组的某个维度和输出数组的对应维度的长度相同或者其长度为 1 时,这个数组能够用来计算,否则出错。
- 当输入数组的某个维度的长度为 1 时,沿着此维度运算时都用此维度上的第一组值。
Numpy 数组操作
1.修改数组的形状
1.1 ndarray.reshape
numpy.reshape(arr, newshape, order=‘C’)
import numpy as np
# 将一维数组转换为一个5x4的数组
arr = np.arange(20)
print(arr)
print(arr.reshape(5, 4))
1.2 ndarray.flat
numpy.ndarray.flat 是一个数组元素迭代器
import numpy as np
arr = np.arange(20)
# print(arr)
arr1 = arr.reshape(5, 4)
# 结果为每一行的元素组成的数组
for element in arr1:
print(element)
# 结果为每一个元素,遍历矩阵的每一个值
for element in arr1.flat:
print(element)
1.3 ndarray.flatten
ndarray.flatten 返回一份数组拷贝,对拷贝所做的修改不会影响原始数组
ndarray.flatten(order=‘C’)
order(可选):‘C’ – 按行,‘F’ – 按列,‘A’ – 原顺序,‘K’ – 元素在内存中的出现顺序。
import numpy as np
arr1 = np.arange(20).reshape(5, 4)
print(arr1)
# 默认按行展开
print(arr1.flatten())
# 按列展开
print(arr1.flatten(order='F'))
1.4 ndarray.ravel
numpy.ravel() 展平的数组元素(扁平化),顺序通常是"C风格",返回的是数组视图(view),修改会影响原始数组。
ndarray.ravel(a, order=‘C’)
import numpy as np
arr1 = np.arange(20).reshape(5, 4)
print(arr1)
arr = arr1.ravel()
print(arr)
print(arr1.ravel(order='F'))
# 修改arr的值,原来的数组arr1的值也发生变化
arr[0] = 100
print(arr)
print(arr1)
2.翻转数组
2.1 numpy.transpose
numpy.transpose(arr, axes)
参数说明:
arr
:要操作的数组axes
:整数列表,对应维度,通常所有维度都会对换。
import numpy as np
# 三维数组
arr = np.arange(16).reshape(2, 2, 4)
print(arr.shape)
# 翻转为(4, 2, 2)
print(np.transpose(arr).shape)
# 翻转为(2, 4, 2)
print(np.transpose(arr, (1, 2, 0)).shape)
2.2 ndarray.T
作用类似与numpy.transpose
import numpy as np
arr = np.arange(12).reshape(3, 4)
print(arr)
print(arr.T)
3.连接数组
numpy.concatenate
numpy.concatenate 函数用于沿指定轴连接相同形状的两个或多个数组
numpy.concatenate((a1, a2, …), axis)
- axis:指定按什么轴进行数组的连接,默认值为0
import numpy as np
arr = np.arange(12).reshape(3, 4)
arr1 = np.linspace(12, 23, 12).reshape(3, 4)
print(arr)
print(arr1)
# 沿着0轴进行连接
print(np.concatenate((arr, arr1)))
# 沿着1轴进行连接
print(np.concatenate((arr, arr1), 1))
4.分割数组
4.1 numpy.split
将一个数组沿着特定的轴分割为多个子数组
numpy.split(ary, indices_or_sections, axis)
ary
:被分割的数组indices_or_sections
:如果是一个整数,就用该数平均切分,如果是一个数组,为沿轴切分的位置(左开右闭)axis
:设置沿着哪个方向进行切分,默认为 0,横向切分,即水平方向。为 1 时,纵向切分,即竖直方向。
import numpy as np
arr = np.arange(9)
# 平均分割为三个子数组
print(np.split(arr, 3))
# 在2, 6的位置出进行分割,范围取值左闭右开
print(np.split(arr, [2, 7]))
arr1 = arr.reshape(3, 3)
# 沿1轴将数组均分为三个子数组
print(np.split(arr1, 3, 1))
4.2 numpy.hsplit和numpy.vsplit
numpy.hsplit 函数用于水平分割数组,通过指定要返回的相同形状的数组数量来拆分原数组。
import numpy as np
arr = np.arange(12).reshape(3, 4)
# 沿水平方向分割数组为相同的两份
print(arr)
print(np.hsplit(arr, 2))
# 沿竖直方向分割为相同的3份
print(np.vsplit(arr, 3))
NumPy 数学函数
三角函数
NumPy 提供了标准的三角函数:sin(),cos(),tan(),arcsin,arccos,和 arctan 函数等
import numpy as np
a = np.array([0, 30, 45, 60, 90])
# 通过pi/180将度数转换为弧度值,再进行运算
sin = np.sin(a*np.pi/180)
print(sin)
cos = np.cos(a*np.pi/180)
print(cos)
tan = np.tan(a*np.pi/180)
print(tan)
# 使用numpy.degrees()函数将反三角函数得到的弧度转换为度数
print(np.degrees(np.arcsin(sin)))
print(np.degrees(np.arccos(cos)))
print(np.degrees(np.arctan(tan)))
舍入函数
numpy.around() 函数返回指定数字的四舍五入值。
numpy.around(a,decimals)
- a: 数组
- decimals: 舍入的小数位数。 默认值为0。 如果为负,整数将四舍五入到小数点左侧的位置
numpy.floor() 返回小于或者等于指定表达式的最大整数,即向下取整。
numpy.ceil() 返回大于或者等于指定表达式的最小整数,即向上取整。
import numpy as np
arr = np.linspace(0, 1, 10)
print(arr)
# 小数点后第一位四舍五入
print(np.around(arr))
# 小数点后第二位四舍五入
print(np.around(arr, decimals=1))
# 小数点前第一位四舍五入
print(np.around(arr, decimals=-1))
# 向下取整
print(np.floor(arr))
# 向上取整
print(np.ceil(arr))
NumPy 算术函数
NumPy 算术函数包含简单的加减乘除: add(),subtract(),multiply() 和 divide()。
注:等同于+,-,*,/
需要注意的是数组必须具有相同的形状或符合数组广播规则。
numpy.reciprocal() 函数返回参数逐元素的倒数。
numpy.power() 函数将第一个输入数组中的元素作为底数,计算它与第二个输入数组中相应元素的幂。等同于“******”运算符
numpy.mod() 计算输入数组中相应元素的相除后的余数。(取模)
import numpy as np
arr = np.array([0.1, 1, 3.2, 100])
# 返回元素倒数
print(np.reciprocal(arr))
# 幂运算
print(np.power(arr, 3))
# 取模
arr1 = np.array([1, 2, 3, 4])
print(np.mod(arr, 2))
print(np.mod(arr, arr1))
NumPy 副本和视图
副本是一个数据的完整的拷贝,如果我们对副本进行修改,它不会影响到原始数据,物理内存不在同一位置。
视图是数据的一个别称或引用,通过该别称或引用亦便可访问、操作原有数据,但原有数据不会产生拷贝。如果我们对视图进行修改,它会影响到原始数据,物理内存在同一位置。
视图(浅拷贝)一般发生在:
- 1、numpy 的切片操作返回原数据的视图。
- 2、调用 ndarray 的 view() 函数产生一个视图。
副本(深拷贝)一般发生在:
- Python 序列的切片操作,调用deepCopy()函数。
- 调用 ndarray 的 copy() 函数产生一个副本。
1、无复制
简单的赋值不会创建数组对象的副本。 相反,它使用原始数组的相同id()来访问它。 id()返回 Python 对象的通用标识符,类似于 C 中的指针。
import numpy as np
a = np.arange(6)
print (a)
print (id(a))
b = a
print (b)
print (id(b))
b.shape = 3,2
print (b)
print (a)
2、视图或浅拷贝
使用ndarray.view() 实现数组的浅拷贝,切片也是一种浅拷贝
import numpy as np
arr = np.arange(12)
arr2=arr.view()
print(arr,arr2,id(arr),id(arr2))
# 改变arr2的元素,arr也将发生变化
arr2[0]=100
print(arr,arr2,id(arr),id(arr2))
a=arr[3:]
b=arr[3:]
a[1]=123
b[2]=234
print(arr)
print(id(a),id(b),id(arr[3:]))
3、副本或深拷贝
ndarray.copy() 函数创建一个副本。 对副本数据进行修改,不会影响到原始数据,它们物理内存不在同一位置。
import numpy as np
a = np.array([[10,10], [2,3], [4,5]])
print (a)
b = a.copy()
print (b)
print (id(a),id(b)
# 改变b的值对原来的数据不产生影响
b[0,0] = 100
print (b)
print (a)
NumPy 矩阵库(Matrix)
NumPy 中包含了一个矩阵库 numpy.matlib,该模块中的函数返回的是一个矩阵,而不是 ndarray 对象。
import numpy as np
arr = np.arange(12).reshape(3, 4)
print(arr)
# 矩阵的转置
print(arr.T)
"""
numpy.empty(shape, dtype, order)
元素为随机生成的
shape: 定义新矩阵形状的整数或整数元组
Dtype: 可选,数据类型
order: C(行序优先) 或者 F(列序优先)
"""
# 创建一个2x2的矩阵
print(np.empty((2, 2)))
# 创建全为0的3x3矩阵
print(np.zeros((3, 3)))
# 创建全为1的3x3矩阵
print(np.ones((3, 3)))
"""
numpy.eye(n, M,k, dtype)
n: 返回矩阵的行数
M: 返回矩阵的列数,默认为 n
k: 对角线的索引
dtype: 数据类型
"""
# 返回一个矩阵,对角线元素为 1,其他位置为零。
print(np.eye(3, 3, 0))
# 指定1的起始位置
print(np.eye(3, 4, 2))
# 创建单位矩阵
print(np.identity(3, dtype=float))
# 创建一个给定大小的矩阵,数据是随机填充的
print(np.random.rand(3, 3))
NumPy 线性代数
函数 | 描述 |
---|---|
dot | 两个数组的点积。 |
vdot | 两个向量的点积 |
inner | 两个数组的内积 |
matmul | 两个数组的矩阵积 |
determinant | 数组的行列式 |
solve | 求解线性矩阵方程 |
inv | 计算矩阵的乘法逆矩阵 |
import numpy as np
arr = np.arange(6).reshape(2, 3)
arr1 = np.arange(7, 13).reshape(3, 2)
print(arr)
print(arr1)
# 两个数组的点积
print(np.dot(arr, arr1))
# 两个向量的点积
print(np.vdot(arr, arr1))
# numpy.inner() 函数返回一维数组的向量内积。对于更高的维度,它返回最后一个轴上的和的乘积。
arr2 = np.arange(7, 13).reshape(2, 3)
print(np.inner(arr, arr2))
# numpy.matmul 函数返回两个数组的矩阵乘积
print(np.matmul(arr, arr1))
# 二维与一维进行运算
b = [1, 2, 3]
print(np.matmul(arr, b))
# 计算矩阵的行列式, 矩阵必须为方阵
arr3 = np.array([[6, 3, 5],
[2, 3, 5],
[9, 4, 7]])
print(np.linalg.det(arr3))
# 线性方程组的解
"""
方程组:
x + y + z = 6
2y + 5z = -4
2x + 5y - z = 27
"""
a = np.array([[1, 1, 1], [0, 2, 5], [2, 5, -1]])
b = np.array([6, -4, 27])
print(np.linalg.solve(a, b))
# 计算矩阵的逆矩阵
a1 = np.linalg.inv(a)
print(a1)
print(np.dot(a, a1))
补充:numpy.random
import numpy as np
# 生成一个或多个 [0, 1) 区间内的均匀分布随机浮点数
print(np.random.random)
# 类似于 random(),但接受形状参数来生成多维数组
print(np.random.rand(3, 4))
# 生成指定范围内的随机整数。生成5个1到10之间的整数
print(np.random.randint(1, 10, 5))
# 从正态分布中生成随机数
"""
numpy.random.normal(loc=0.0, scale=1.0, size=None)
loc:表示正态分布的均值(μ),这是分布的中心点,默认值为 0.0
scale:表示标准差(σ),必须是非负数,它是正态分布的宽度度量。默认值为 1.0。
size:定义输出数组的形状,如果未给定或为 None,则返回单个浮点数;
如果是整数 n,则返回 n 个元素的数组;如果是元组 (d1, d2, ..., dn),
则返回形状为 (d1, d2, ..., dn) 的数组
"""
print(np.random.normal(loc=0.0, scale=1.0, size=None))
# 从均匀分布中生成随机数
print(np.random.uniform(low=0.0, high=1.0, size=None))
# 从给定的一组值中随机选择元素
arr = np.arange(6)
print(np.random.choice(arr, 3))
# 在原地打乱一个序列或数组
np.random.shuffle(arr)
print(arr)