numpy

用于数值计算

  • ndarray, 一个有效的多维数组,能提供以数组为导向的快速数值计算和灵活的广播功能(broadcasting)
  • 便利的数学函数
  • 用于读取/写入(reading/writing)数据到磁盘的便利工具
  • 线性代数,随机数生成,傅里叶变换能力
  • 可以用C API来写C,C++,或FORTRAN

ndarray

N-dimensional array object(n维数组对象)

# 生成一个随机数组
import numpy as np
data = np.random.randn(2, 3)
print(data.shape) # shape表示维度
print(data.dtype) # data type, output:dtype('float64')

创建

# list类型转化
data1 = [6, 7.5, 8, 0, 1]
arr1 = np.array(data1) # 自动分配data type
# 嵌套的list也可
data2 = [[1, 2, 3, 4], [5, 6, 7, 8]]
arr2 = np.array(data2)
print(arr2.ndim) # 输出维度
# 其他创建方式
np.zeros(10)
np.zeros((3, 6))
np.empty((2, 3, 4)) # 其中内容相当于未初始化的数组,而非0
np.arange(15) # output:array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])

数据类型

arr1 = np.array([1, 2, 3], dtype=np.float64) # 指定为浮点型
# astype:类型转化,总是会返回一个新的数组
arr = np.array([1, 2, 3, 4, 5])
float_arr = arr.astype(np.float64) # 用astype转化类型
numeric_strings = np.array(['1.25', '-9.6', '42'], dtype=np.string_)
numeric_strings.astype(float) # string也能转
# 使用其他数组的dtype定制类型
int_array = np.arange(10)
calibers = np.array([.22, .270, .357, .380, .44, .50], dtype=np.float64)
print(int_array.astype(calibers.dtype))

计算

不需要for,任何两个大小相等的数组,运算都是点对点

element-wise 点对点,就是指两个数组的运算,在同一位置的元素间才会进行运算。

这种算数操作如果涉及标量(scalar)的话,会涉及到数组的每一个元素:

arr = np.array([[1., 2., 3.], [4., 5., 6.]])
arr * arr # array([[ 1., 4., 9.], [ 16., 25., 36.]])
arr - arr # array([[ 0., 0., 0.], [ 0., 0., 0.]])
1 / arr # array([[ 1. , 0.5 , 0.33333333], [ 0.25 , 0.2 , 0.16666667]])
arr2 = np.array([[0., 4., 1.], [7., 2., 12.]])
arr2 > arr # array([[False, True, False], [ True, False, True]], dtype=bool)

基本索引和切片

array的切片后的结果只是一个views(视图),用来代表原有array对应的元素,而不是创建了一个新的array。但list里的切片是产生了一个新的list

# 和列表的区别:broadcasted(广式转变)
arr = np.arange(10)
arr1[5:8] = 12 # 如果是列表,会报错:TypeError: can only assign an iterable
# 数组切片的结果类似于指针
arr_slice = arr[5:8]
arr_slice[:] = 64 # 赋值给arr[5:8]的所有元素 array([ 0, 1, 2, 3, 4, 64, 64, 64, 8, 9])
# 二维数组单一索引指一维数组
arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
arr2d[2] # array([7, 8, 9])
# 访问单一元素
arr2d[0][2]
arr2d[0, 2]
# 多维数组: 返回一个低维度的多维数组
arr3d = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
arr3d[0] # np.array([[1, 2, 3], [4, 5, 6]])
# 用标量赋值
old_values = arr3d[0].copy()
arr3d[0] = 42 # array([[[42, 42, 42],[42, 42, 42]], [[ 7, 8, 9],[10, 11, 12]]])
# 用数组赋值
arr3d[0] = old_values # array([[[ 1, 2, 3],[ 4, 5, 6]], [[ 7, 8, 9],[10, 11, 12]]])

切片后返回的数组都是views

用切片索引

# 选中前两行
arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
arr2d[:2] # array([[1, 2, 3],[4, 5, 6]])
# 区别
arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
list2d = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
# 由于数组更兼容的访问方式
arr2d[1,1] # 5,但list2d[1,1]会报错
# 因此数组可以通过下列方式切片,但列表不能
arr2d[:, 1:] # array([[2,3], [5,6], [8,9]])

bool索引

通过布尔值作为数组的索引

score = np.array([45, 68, 95, 35, 77, 44, 60])
reward = np.random.randn(7, 3)
reward[score > 60] # 输出reward的2,3,5,7行
reward[score > 60, 1] # 输出reward的2,3,5,7行2列的一维数组
布尔运算 符号 说明
取反 !=~
& and无效
` `

用布尔索引总是会返回一份新创建的数据,原本的数据不会被改变。

# 改变所有行或列
reward[score > 70] = 100 # 改变3,5行的所有值
reward[:, 条件] = 100

花式索引

会套两层[[]],得到的是一个新的array

arr = np.empty((8, 4))
for i in range(8):
arr[i] = i
# 按一定顺序选出几行
arr[[4, 3, 0, 6]] # array([[ 4., 4., 4., 4.], [ 3., 3., 3., 3.], [ 0., 0., 0., 0.], [ 6., 6., 6., 6.]])
arr[[-3, -5, -7]] # array([[ 5., 5., 5., 5.],[ 3., 3., 3., 3.],[ 1., 1., 1., 1.]])
arr = np.arange(32).reshape((8, 4))
arr[[1, 5, 7, 2], [0, 3, 1, 2]] # array([ 4, 23, 29, 10])

可以看到[ 4, 23, 29, 10]分别对应(1, 0), (5, 3), (7, 1), (2, 2)。不论数组有多少维,fancy indexing的结果总是一维。

arr[[1, 5, 7, 2]][:, [0, 3, 1, 2]] # array([[ 4,  7,  5,  6], [20, 23, 21, 22], [28, 31, 29, 30], [ 8, 11,  9, 10]])

上面的意思是,先从arr中选出[1, 5, 7, 2]这四行:

  array([[ 4,  5,  6,  7],
[20, 21, 22, 23],
[28, 29, 30, 31],
[ 8, 9, 10, 11]])

然后[:, [0, 3, 1, 2]]表示选中所有行,但是列的顺序要按0,3,1,2来排。于是得到:

array([[ 4,  7,  5,  6],
[20, 23, 21, 22],
[28, 31, 29, 30],
[ 8, 11, 9, 10]])

数组转置和轴交换

常用于矩阵乘法

转置也是返回一个view,而不是新建一个数组。有两种方式,一个是transpose方法,一个是T属性

# T属性
arr = np.arange(15).reshape((3, 5))
'''
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])'''
arr.T
'''output
array([[ 0, 5, 10],
[ 1, 6, 11],
[ 2, 7, 12],
[ 3, 8, 13],
[ 4, 9, 14]])'''
# transpose会接受由轴数字组成的tuple,来交换轴:
arr = np.arange(16).reshape((2, 2, 4))
'''
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7]], [[ 8, 9, 10, 11],
[12, 13, 14, 15]]])'''
arr.transpose((1, 0, 2))
'''output
array([[[ 0, 1, 2, 3],
[ 8, 9, 10, 11]], [[ 4, 5, 6, 7],
[12, 13, 14, 15]]])'''
# swapaxes方法:取两个axis值,并交换这两个轴:
arr.swapaxes(1, 2) # 直交换second axis和last axis
'''
array([[[ 0, 4],
[ 1, 5],
[ 2, 6],
[ 3, 7]], [[ 8, 12],
[ 9, 13],
[10, 14],
[11, 15]]])'''

通用函数

快速点对点函数

一元通用函数

需要一个数组

arr = np.arange(10)
np.sqrt(arr) # 开方
np.exp(arr) # e^x
函数名 描述
np.abs(x) 返回数组的绝对值
np.fabs(x) 返回数组的绝对值(忽略复数)
np.sqrt(x) 返回数组的平方根
np.square(x) 返回数组的平方
np.exp(x) 返回数组的指数值 \(e^x\)
np.log(x) 返回数组的自然对数
np.log10(x) 返回数组的以10为底的对数
np.log2(x) 返回数组的以2为底的对数
np.sign(x) 返回数组的符号值,1表示正数,-1表示负数,0表示零
np.ceil(x) 返回数组的上限值,即大于等于每个元素的最小整数
np.floor(x) 返回数组的下限值,即小于等于每个元素的最大整数
np.rint(x) 返回数组的四舍五入值,保留到最近的整数
np.modf(x) 将数组拆分为小数部分和整数部分
np.isnan(x) 返回一个布尔数组,指示每个元素是否为 NaN
np.isinf(x) 返回一个布尔数组,指示每个元素是否为无穷大
np.cos(x) 返回数组中每个元素的余弦值
np.sin(x) 返回数组中每个元素的正弦值
np.tan(x) 返回数组中每个元素的正切值
np.arccos(x) 返回数组中每个元素的反余弦值
np.arcsin(x) 返回数组中每个元素的反正弦值
np.arctan(x) 返回数组中每个元素的反正切值
np.degrees(x) 将数组中每个元素从弧度转换为角度
np.radians(x) 将数组中每个元素从角度转换为弧度
np.exp2(x) 返回数组的指数值 \(2^x\)
np.expm1(x) 返回数组的指数值 \(e^x-1\)
np.log1p(x) 返回数组的对数值 \(log_e(x+1)\)
np.deg2rad(x) 将数组中每个元素从角度转换为弧度
np.rad2deg(x) 将数组中每个元素从弧度转换为角度

二元通用函数

需要两个数组

x = np.random.randn(8)
y = np.random.randn(8)
np.maximum(x, y) # 最大值
arr = np.array([3.14, 2.718, 1.414, 0.618])
# 使用 np.modf 将数组拆分为整数部分和小数部分
fractional, integral = np.modf(arr)
# 打印结果
print("原始数组:", arr)
print("小数部分:", fractional)
print("整数部分:", integral)
# ufunc能接受一个可选参数作为输出,这样可以直接更改原有的数组:
np.sqrt(arr) # 没有改变原有的arr
np.sqrt(arr, arr) # 改变了原有的arr
函数名 描述
np.add(x1, x2) 返回两个数组的逐元素和
np.subtract(x1, x2) 返回两个数组的逐元素差
np.multiply(x1, x2) 返回两个数组的逐元素乘积
np.divide(x1, x2) 返回两个数组的逐元素除法
np.power(x1, x2) 返回两个数组的逐元素幂运算结果
np.mod(x1, x2) 返回两个数组的逐元素取模结果
np.remainder(x1, x2) 返回两个数组的逐元素求余结果
np.fmax(x1, x2) 返回两个数组的逐元素最大值
np.fmin(x1, x2) 返回两个数组的逐元素最小值
np.maximum(x1, x2) 返回两个数组的逐元素最大值,其中 NaN 被视为无限大
np.minimum(x1, x2) 返回两个数组的逐元素最小值,其中 NaN 被视为无限小
np.copysign(x1, x2) 返回 x1 的符号与 x2 相同的数组
np.greater(x1, x2) 返回一个布尔数组,指示 x1 中的每个元素是否大于 x2 中的对应元素
np.greater_equal(x1, x2) 返回一个布尔数组,指示 x1 中的每个元素是否大于等于 x2 中的对应元素
np.less(x1, x2) 返回一个布尔数组,指示 x1 中的每个元素是否小于 x2 中的对应元素
np.less_equal(x1, x2) 返回一个布尔数组,指示 x1 中的每个元素是否小于等于 x2 中的对应元素
np.equal(x1, x2) 返回一个布尔数组,指示 x1 中的每个元素是否等于 x2 中的对应元素
np.not_equal(x1, x2) 返回一个布尔数组,指示 x1 中的每个元素是否不等于 x2 中的对应元素
np.logical_and(x1, x2) 返回一个布尔数组,指示 x1 和 x2 中的对应元素是否都为 True
np.logical_or(x1, x2) 返回一个布尔数组,指示 x1 和 x2 中的对应元素是否至少有一个为 True
np.logical_xor(x1, x2) 返回一个布尔数组,指示 x1 和 x2 中的对应元素是否恰好有一个为 True
np.arctan2(x1, x2) 返回两个数组中每个元素的反正切值

数组导向编程

网格

meshgrid函数用两个坐标轴上的点在平面上画网格。用法:

  • [X,Y]=meshgrid(x,y)

  • [X,Y]=meshgrid(x)[X,Y]=meshgrid(x,x)是等同的

  • [X,Y,Z]=meshgrid(x,y,z)生成三维数组,可用来计算三变量的函数和绘制三维立体图

[X,Y] = meshgrid(x,y) 将向量x和y定义的区域转换成矩阵X和Y,其中矩阵X的行向量是向量x的简单复制,而矩阵Y的列向量是向量y的简单复制(注:下面代码中X和Y均是数组,在文中统一称为矩阵了)。

假设x是长度为m的向量,y是长度为n的向量,则最终生成的矩阵X和Y的维度都是 nm

X, Y = np.meshgrid(x, y) # X = [x, x, .., x] Y = [y变为列向量拼接而成]
m, n = (5, 3)
x = np.linspace(0, 1, m) # 生成5个[0,1]之间的等间隔数字序列
y = np.linspace(0, 1, n)
X, Y = np.meshgrid(x, y)
X.shape, y.shape # (3, 5) (3, 5)
# 绘制网格
import matplotlib.pyplot as plt
%matplotlib inline
plt.style.use('ggplot') plt.plot(X, Y, marker='.', color='blue', linestyle='none')
# 用zip得到网格平面的坐标数据
z = [i for i in zip(X.flat, Y.flat)] # .flat:将多维数组展成一维,zip:将可迭代对象打包为元组

python中可迭代的对象:

  • 列表(List)
  • 元组(Tuple)
  • 字符串(String)
  • 集合(Set)
  • 字典(Dictionary)
  • 文件对象(File)
  • range 对象(Range)
  • 迭代器对象(Iterator)
  • 生成器对象(Generator)

数组-逻辑条件

numpy.where函数是一个向量版的三相表达式,x if condition else y

# where 第二个参数和第三个参数不必是数组
xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])
yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])
cond = np.array([True, False, True, True, False])
result = np.where(cond, xarr, yarr) # array([ 1.1, 2.2, 1.3, 1.4, 2.5])

数学和统计方法

函数 描述
numpy.sum 计算数组或某个轴向上的元素总和
numpy.cumsum 计算数组或某个轴向上的元素累积和
numpy.mean 计算数组或某个轴向上的元素平均值
numpy.std 计算数组或某个轴向上的元素标准差
numpy.var 计算数组或某个轴向上的元素方差
numpy.min 找出数组或某个轴向上的最小值
numpy.max 找出数组或某个轴向上的最大值
numpy.argmin 找出数组或某个轴向上的最小值的索引值
numpy.argmax 找出数组或某个轴向上的最大值的索引值
numpy.median 计算数组或某个轴向上的元素中位数
numpy.percentile 计算数组或某个轴向上的元素在指定百分位数处的值
numpy.any 判断数组或某个轴向上是否有任意一个元素为 True
numpy.all 判断数组或某个轴向上是否所有元素都为 True
numpy.ptp 计算数组或某个轴向上的元素峰值-峰值距离

轴向参数:axis=0 | 1

布尔数组

有两个其他方法,any和all,对于布尔数组特别有用。any检测数组中只要有一个ture返回就是true,而all检测数组中都是true才会返回true。

arr = np.random.randn(100)
(arr > 0).sum() # Number of positive values

排序

# sort 二维
arr.sort(0) # 排列向量,默认是0
arr.sort(1) # 排行向量
# np.sort 不改变原有数组
np.sort(a, axis=-1, kind=None, order=None)

单一性

# unqiue 排序&不重复
names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
np.unique(names) # array(['Bob', 'Joe', 'Will'], dtype='<U4')
# 一个数组中是否存在另一个数组的值
values = np.array([6, 0, 0, 3, 2, 5, 6])
np.in1d(values, [2, 3, 6]) # array([ True, False, False, True, True, False, True], dtype=bool)

运算

运算 用例 \(a*b\) np.multiple(a,b) np.matmul(a,b) np.dot(a,b) a@b
向量 \(\begin{bmatrix} 0&1\end{bmatrix} \begin{bmatrix}1&2\end{bmatrix}\) \(\begin{bmatrix}0&2\end{bmatrix}\) \(\begin{bmatrix}0&2\end{bmatrix}\) 2 2 2
不同维度的多维数组(np.array) \(\begin{bmatrix}1&2\\3&4\\5&6\end{bmatrix} \begin{bmatrix}1\\2\end{bmatrix}\) ValueError ValueError \(\begin{bmatrix}5\\11\\17\end{bmatrix}\) \(\begin{bmatrix}5\\11\\17\end{bmatrix}\) \(\begin{bmatrix}5\\11\\17\end{bmatrix}\)
同维的多维数组(np.array) $\begin{bmatrix}0&1\2&3\end{bmatrix} \begin{bmatrix}2&3\4&5\end{bmatrix} $ \(\begin{bmatrix}0&3\\8&15\end{bmatrix}\) \(\begin{bmatrix}0&3\\8&15\end{bmatrix}\) \(\begin{bmatrix}4&5\\16&21\end{bmatrix}\) \(\begin{bmatrix}4&5\\16&21\end{bmatrix}\) \(\begin{bmatrix}4&5\\16&21\end{bmatrix}\)
矩阵(np.array) $\begin{bmatrix}0&1\2&3\end{bmatrix} \begin{bmatrix}2&3\4&5\end{bmatrix} $ \(\begin{bmatrix}4&5\\16&21\end{bmatrix}\) \(\begin{bmatrix}0&3\\8&15\end{bmatrix}\) \(\begin{bmatrix}4&5\\16&21\end{bmatrix}\) \(\begin{bmatrix}4&5\\16&21\end{bmatrix}\) \(\begin{bmatrix}4&5\\16&21\end{bmatrix}\)

推荐

  • 对应项相乘用np.multiple(a,b)
  • 矩阵乘法用np.dot(a,b)np.matmul(a,b)

Numpy,一篇足以的更多相关文章

  1. numpy基础篇-简单入门教程4

    np.set_printoptions(precision=3),只显示小数点后三位 np.random.seed(100) rand_arr = np.random.random([2, 2]) n ...

  2. numpy基础篇-简单入门教程3

    np import numpy as np np.__version__ print(np.__version__) # 1.15.2 numpy.arange(start, stop, step, ...

  3. numpy基础篇-简单入门教程2

    import numpy as np Array 数组 print(np.zeros((2, 2))) # [[0. 0.] [0. 0.]] print(np.ones((2, 2))) # [[1 ...

  4. numpy基础篇-简单入门教程1

    np.split(A, 4, axis=1),np.hsplit(A, 4) 分割 A = np.arange(12).reshape((3, 4)) # 水平方向的长度是4 print(np.spl ...

  5. Numpy——进阶篇

    impoort numpy as np arr=np.arange(10) #输出奇数 arr[arr%2==1] #将arr中的所有奇数替换为-1,而不改变arr out=np.where(arr% ...

  6. iOS Reactivecocoa(RAC)知其所以然(源码分析,一篇足以)

    前言 如今RAC大行其道,对其讲解的博客也多不胜数,稍微有点经验的估计也已经对这个爽到不要不要的框架运用自如了,真正沉下来研究其实现原理的估计也不在少数,这里仅仅是记录一下自己的分析理解,更是在写这篇 ...

  7. [学习笔记] NumPy走一趟(持续更)

    Numpy学习笔记 之前没有花时间去专门学Numpy,都是用到什么就草草查一下,最近在学DeepLearning,就决定还是系统地把Numpy学一遍. 一.Numpy基础篇 https://www.r ...

  8. MySQL 异常有这一篇就够了!

    摘要:在本文中,总结了开发过程中最为常见的几种 MySQL 抛出的异常以及如何解决,包括高版本驱动的问题.时区配置问题.SSL 连接问题等,是一篇经验总结贴. 前言 在本文中,总结了开发过程中最为常见 ...

  9. 从零开始学习jQuery (五) 事件与事件对象

    本系列文章导航 从零开始学习jQuery (五) 事件与事件对象 一.摘要 事件是脚本编程的灵魂. 所以本章内容也是jQuery学习的重点. 本文将对jQuery中的事件处理以及事件对象进行详细的讲解 ...

  10. TGL站长关于常见问题的回复

    问题地址: http://www.thegrouplet.com/thread-112923-1-1.html 问题: 网站配有太多的模板是否影响网站加载速度 月光答复: wp不需要删除其他的模板,不 ...

随机推荐

  1. 2023-03-14:读取摄像头,并且显示视频。代码用go语言编写。

    2023-03-14:读取摄像头,并且显示视频.代码用go语言编写. 答案2023-03-14: 大体流程如下: 导入所需的库和包. 初始化 ffmpeg 和 SDL2 库. 打开摄像头并创建 AVF ...

  2. 2020-08-23:描述HTTPS和HTTP的区别。

    福哥答案2020-08-23: 1.地址区别http:http://开头.https:https://开头. 2.默认端口区别http:端口80.https:端口443. 3.数据传输区别http:明 ...

  3. 2020-11-23:go中,s是一个字符串,s[0]代表什么?是否等于固定字节数?

    福个答案2020-11-23:Golang 的字符串(string)是合法的 UTF-8 序列,这就涉及到了两种不同的遍历方式,一种是按照 Unicode 的 codepoint 遍历,另一种是把 s ...

  4. Django4全栈进阶之路12 render 函数和 redirect 函数

    在 Django 中,你可以使用 render 函数来渲染模板并将其返回给客户端,也可以使用 redirect 函数来重定向到其他 URL. 在 Django 中,render 函数和 redirec ...

  5. 【编程日记】搭建python开发环境

    0.相关确定 0.1确定操作系统 Python是一种跨平台的编程语言,这意味着它能够运行在所有主要的操作系统中.然而,在不同的操作系统(Windows/Mac/Linux)中,安装Python的方法存 ...

  6. 代码随想录算法训练营Day14 二叉树

    代码随想录算法训练营 代码随想录算法训练营Day14 二叉树|理论基础 递归遍历 基础知识 二叉树都是通过栈来实现的. 二叉树的种类 在我们解题过程中二叉树有两种主要的形式:满二叉树和完全二叉树. 满 ...

  7. 人工智能导论——机器人自动走迷宫&强化学习

    一.问题重述 强化学习是机器学习中重要的学习方法之一,与监督学习和非监督学习不同,强化学习并不依赖于数据,并不是数据驱动的学习方法,其旨在与发挥智能体(Agent)的主观能动性,在当前的状态(stat ...

  8. 6.4. HttpClient

    1. 什么是HttpClient? HttpClient是Java 11中引入的一个新特性,用于支持同步和异步发送HTTP请求以及处理HTTP响应.它提供了简单易用的API,使得发送HTTP请求变得非 ...

  9. substrate 编译出错unresolved import `sp_runtime::testing` failed to resolve: could not find `GenesisConfig` in `system`

    error[E0432]: unresolved import `sp_runtime::testing` --> /Users/suyinrong/bitcoin-proj/substrate ...

  10. ZYNQ 启动过程简介 以及 ZYNQ 裸机生成BOOT.BIN

    背景 下图是ZYNQ的启动过程 上电复位等完成后,先执行BootRom,然后再根据MIO设定的启动方式选择对应从哪里启动,无论从哪里启动,都需要一个BOOT.BIN文件,对于裸机程序来说: BOOT. ...