快捷搜索:  汽车  科技

python使用numpy求数组最大值(用Python做科学计算工具篇)

python使用numpy求数组最大值(用Python做科学计算工具篇)更接近硬件(效率)用于多维数组的 Python 扩展包高级数字对象:整型、浮点型容器:列表(无成本的插入和追加)、字典(快速查找)NumPy提供:

目录

  • 什么是 numpy 和 NumPy 数组?
  • 创建数组
  • 基本数据类型
  • 基本可视化
  • 索引和切片
  • 副本和查看
  • 花式索引

1.1.1. 什么是 NumPy 和 NumPy 数组?

NumPy 数组

Python对象:

高级数字对象:整型、浮点型

容器:列表(无成本的插入和追加)、字典(快速查找)

NumPy提供:

用于多维数组的 Python 扩展包

更接近硬件(效率)

专为科学计算而设计(方便)

也称为面向矩阵的计算

>>> >>> import numpy as np >>> a = np.array([0 1 2 3]) >>> a array([0 1 2 3])

例如,一个包含以下内容的数组:

  • 离散时间步长的实验/模拟值
  • 测量设备记录的信号,例如声波
  • 图像的像素,灰度或颜色
  • 在不同 XYZ 位置测量的 3-D 数据,例如 MRI 扫描

为什么有用:提供快速数值运算的内存高效容器。

In [1]: L = range(1000) In [2]: %timeit [i**2 for i in L] 1000 loops best of 3: 403 us per loop In [3]: a = np.arange(1000) In [4]: %timeit a**2 100000 loops best of 3: 12.7 us per loop

NumPy 参考文档

  • 在网络上:https : //numpy.org/doc/
  • 互动帮助:

In [5]: np.array? String Form:<built-in function array> Docstring: array(object dtype=None copy=True order=None subok=False ndmin=0 ...

  • 寻找东西:

>>> >>> np.lookfor('create array') Search results for 'create array' --------------------------------- numpy.array Create an array. numpy.memmap Create a memory-map to an array stored in a *binary* file on disk. In [6]: np.con*? np.concatenate np.conj np.conjugate np.convolve

导入约定

导入 numpy 的推荐约定是:

>>> >>> import numpy as np

1.1.2. 创建数组

手动构建数组

  • 一维:

>>> >>> a = np.array([0 1 2 3]) >>> a array([0 1 2 3]) >>> a.ndim 1 >>> a.shape (4 ) >>> len(a) 4

  • 2-D 3-D ... :

>>> >>> b = np.array([[0 1 2] [3 4 5]]) # 2 x 3 array >>> b array([[0 1 2] [3 4 5]]) >>> b.ndim 2 >>> b.shape (2 3) >>> len(b) # returns the size of the first dimension 2 >>> c = np.array([[[1] [2]] [[3] [4]]]) >>> c array([[[1] [2]] [[3] [4]]]) >>> c.shape (2 2 1)

练习:简单数组

  • 创建一个简单的二维数组。首先,重做上面的例子。然后创建您自己的:如何在第一行倒数奇数,在第二行倒数偶数?
  • 在这些数组上使用函数len() numpy.shape()。它们之间的关系如何?以及ndim数组的属性?

用于创建数组的函数

在实际中,我们不可能一个一个地手动输入数组元素......

  • 均匀分布的:

>>> >>> a = np.arange(10) # 0 .. n-1 (!) >>> a array([0 1 2 3 4 5 6 7 8 9]) >>> b = np.arange(1 9 2) # start end (exclusive) step >>> b array([1 3 5 7])

  • 或按点数:

>>> >>> c = np.linspace(0 1 6) # start end num-points >>> c array([0. 0.2 0.4 0.6 0.8 1. ]) >>> d = np.linspace(0 1 5 endpoint=False) >>> d array([0. 0.2 0.4 0.6 0.8])

  • 常用数组:

>>> >>> a = np.ones((3 3)) # reminder: (3 3) is a tuple >>> a array([[1. 1. 1.] [1. 1. 1.] [1. 1. 1.]]) >>> b = np.zeros((2 2)) >>> b array([[0. 0.] [0. 0.]]) >>> c = np.eye(3) >>> c array([[1. 0. 0.] [0. 1. 0.] [0. 0. 1.]]) >>> d = np.diag(np.array([1 2 3 4])) >>> d array([[1 0 0 0] [0 2 0 0] [0 0 3 0] [0 0 0 4]])

  • np.random:随机数(Mersenne Twister PRNG):

>>> >>> a = np.random.rand(4) # uniform in [0 1] >>> a array([ 0.95799151 0.14222247 0.08777354 0.51887998]) >>> b = np.random.randn(4) # Gaussian >>> b array([ 0.37544699 -0.11425369 -0.47616538 1.79664113]) >>> np.random.seed(1234) # Setting the random seed

练习:使用函数创建数组

  • 与试验arange,linspace,ones,zeros,eye和 diag。
  • 使用随机数创建不同类型的数组。
  • 在创建具有随机值的数组之前尝试设置种子。
  • 看看功能np.empty。它有什么作用?这什么时候有用?

1.1.3. 基本数据类型

大家可能已经注意到,在某些情况下,数组元素以尾随点显示(例如2.vs 2)。这是由于使用的数据类型不同:

>>> >>> a = np.array([1 2 3]) >>> a.dtype dtype('int64') >>> b = np.array([1. 2. 3.]) >>> b.dtype dtype('float64')

不同的数据类型允许我们在内存中更紧凑地存储数据,但大多数时候我们只是使用浮点数。请注意,在上面的示例中,NumPy 会自动检测输入中的数据类型。

你可以明确指定所需的数据类型:

>>> >>> c = np.array([1 2 3] dtype=float) >>> c.dtype dtype('float64')

默认的数据类型是浮点型:

>>> >>> a = np.ones((3 3)) >>> a.dtype dtype('float64')

还有其他类型:

复杂的:

>>>

>>> d = np.array([1 2j 3 4j 5 6*1j])

>>> d.dtype

dtype('complex128')

布尔:

>>>

>>> e = np.array([True False False True])

>>> e.dtype

dtype('bool')

字符串:

>>>

>>> f = np.array(['Bonjour' 'Hello' 'Hallo'])

>>> f.dtype # <--- strings containing max. 7 letters

dtype('S7')

更多的:

int32

int64

uint32

uint64

1.1.4. 基本可视化

现在我们有了第一个数据数组,我们将把它们可视化。

首先启动Spyder:

>>> >>> %matplotlib

或者,从笔记本中,在笔记本中启用绘图:

>>> >>> %matplotlib inline

绘图显示在笔记本中而不是在新窗口中。

  • 一维绘图:

>>> import numpy as np import matplotlib.pyplot as plt #X轴,Y轴数据 x = np.arange(0 7) y = [0.3 0.4 2 5 3 4.5 4] plt.figure(figsize=(8 4)) #创建绘图对象 plt.plot(x y ":ro" linewidth=1) #在当前绘图对象绘图(X轴,Y轴,蓝色虚线,线宽度) plt.xlabel("Time(s)") #X轴标签 plt.ylabel("Volt") #Y轴标签 plt.title("Line plot") #图标题 plt.grid(True) #添加网格 plt.show() #显示图

python使用numpy求数组最大值(用Python做科学计算工具篇)(1)

  • 二维数组:

from matplotlib import pyplot as mpl import numpy as np data=np.clip(np.random.randn(5 5) -1 1) #生成随机数据 5行5列 最大值1 最小值-1 fig = plt.figure() # 第一个子图 按照默认配置 ax = fig.add_subplot(221) ax.imshow(data) # 第二个子图 使用自定义的colormap ax = fig.add_subplot(222) cmap=mpl.cm.cool #可以使用自定义的colormap ax.imshow(data cmap=cmap) # 第三个子图增加一个colorbar ax = fig.add_subplot(223) cmap=mpl.cm.hot #可以使用自定义的colormap im=ax.imshow(data cmap=cmap) plt.colorbar(im) ## 第四个子图可以调整colorbar ax = fig.add_subplot(224) cmap = mpl.cm.winter im=ax.imshow(data cmap=cmap) plt.colorbar(im cmap=cmap ticks=[-1 0 1]) plt.show()

python使用numpy求数组最大值(用Python做科学计算工具篇)(2)

三维图

import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D fig = plt.figure() ax = Axes3D(fig) X = np.arange(-4 4 0.25) Y = np.arange(-4 4 0.25) X Y = np.meshgrid(X Y) R = np.sqrt(X**2 Y**2) Z = np.sin(R) ax.plot_surface(X Y Z rstride=1 cstride=1 cmap='hot') plt.show()

python使用numpy求数组最大值(用Python做科学计算工具篇)(3)

import numpy as np import matplotlib.pyplot as plt n = 8 X Y = np.mgrid[0:n 0:n] plt.quiver(X Y) plt.show()

python使用numpy求数组最大值(用Python做科学计算工具篇)(4)

练习:简单的可视化

  • 绘制一些简单的数组:作为时间函数的余弦和二维矩阵。
  • 尝试gray在 2D 矩阵上使用颜色图。

1.1.5. 索引和切片

可以像其他 Python 序列(例如列表)一样访问和分配数组的项:

>>> >>> a = np.arange(10) >>> a array([0 1 2 3 4 5 6 7 8 9]) >>> a[0] a[2] a[-1] (0 2 9)

索引从 0 开始,就像其他 Python 序列(和 C/C )一样。相比之下,在 Fortran 或 Matlab 中,索引从 1 开始。

支持用于逆序列的常用 Python 语法:

>>> >>> a[::-1] array([9 8 7 6 5 4 3 2 1 0])

对于多维数组,索引是整数元组:

>>> >>> a = np.diag(np.arange(3)) >>> a array([[0 0 0] [0 1 0] [0 0 2]]) >>> a[1 1] 1 >>> a[2 1] = 10 # 赋值第三行第二列元素为10 >>> a array([[ 0 0 0] [ 0 1 0] [ 0 10 2]]) >>> a[1] array([0 1 0])

笔记

  • 在 2D 中,第一个维度对应rows,第二个维度对应columns
  • 对于多维a,a[0]通过获取未指定维度中的所有元素来解释。

切片:数组,像其他 Python 序列一样也可以切片:

>>> >>> a = np.arange(10) >>> a array([0 1 2 3 4 5 6 7 8 9]) In [15]:a[2:10:2] # [start:end:step] Out[15]: array([2 4 6 8])

请注意,不包括最后一个索引!:

a[:4] array([0 1 2 3])

不需要所有三个切片组件:默认情况下,start为 0, end为最后一个,step为 1:

>>> >>> a[1:3] array([1 2]) >>> a[::2] array([0 2 4 6 8]) >>> a[3:] array([3 4 5 6 7 8 9])

NumPy 索引和切片的一个小插图

python使用numpy求数组最大值(用Python做科学计算工具篇)(5)

您还可以结合分配和切片:

>>> >>> a = np.arange(10) >>> a[5:] = 10 >>> a array([ 0 1 2 3 4 10 10 10 10 10]) >>> b = np.arange(5) >>> a[5:] = b[::-1] >>> a array([0 1 2 3 4 4 3 2 1 0])

练习:索引和切片

  • 尝试不同风格的切片,使用start end和 step: 从 linspace 开始,尝试获得向后计数的奇数和向前计数的偶数。
  • 重现上图中的切片。你可以使用以下表达式来创建数组:

>>> >>> np.arange(6) np.arange(0 51 10)[: np.newaxis] array([[ 0 1 2 3 4 5] [10 11 12 13 14 15] [20 21 22 23 24 25] [30 31 32 33 34 35] [40 41 42 43 44 45] [50 51 52 53 54 55]])

练习:数组创建

创建以下数组(具有正确的数据类型):

[[1 1 1 1] [1 1 1 1] [1 1 1 2] [1 6 1 1]] [[0. 0. 0. 0. 0.] [2. 0. 0. 0. 0.] [0. 3. 0. 0. 0.] [0. 0. 4. 0. 0.] [0. 0. 0. 5. 0.] [0. 0. 0. 0. 6.]]

课程标准:每人 3 个陈述

提示:可以像访问列表一样访问单个数组元素,例如a[1]或。a[1 2]

提示:检查 .doc 的文档字符串diag。

练习:用于创建数组的平铺

浏览 的文档np.tile,并使用此函数构造数组:

[[4 3 4 3 4 3] [2 1 2 1 2 1] [4 3 4 3 4 3] [2 1 2 1 2 1]]

1.1.6. 复制和查看

切片操作在原始数组上创建查看,这只是访问数组数据的一种方式。因此原始数组不会复制到内存中。你可以使用np.may_share_memory()检查两个数组是否共享同一个内存块。但是请注意,这使用了启发式方法,可能会误报。

修改查看时,原始数组也被修改

>>> >>> a = np.arange(10) >>> a array([0 1 2 3 4 5 6 7 8 9]) >>> b = a[::2] >>> b array([0 2 4 6 8]) >>> np.may_share_memory(a b) True >>> b[0] = 12 >>> b array([12 2 4 6 8]) >>> a # (!) array([12 1 2 3 4 5 6 7 8 9]) >>> a = np.arange(10) >>> c = a[::2].copy() # force a copy >>> c[0] = 12 >>> a array([0 1 2 3 4 5 6 7 8 9]) >>> np.may_share_memory(a c) False

这种行为乍一看可能令人惊讶……但它可以节省内存和时间。

工作示例:素数筛

python使用numpy求数组最大值(用Python做科学计算工具篇)(6)

用筛子计算 0-99 之间的素数

  • 构造一个形状 (100 ) 布尔数组is_prime,在开始时填充 True:

>>> >>> is_prime = np.ones((100 ) dtype=bool)

  • 划掉不是素数的 0 和 1:

>>> >>> is_prime[:2] = 0

  • 对于j从 2 开始的每个整数,划掉其更高的倍数:

>>> >>> N_max = int(np.sqrt(len(is_prime) - 1)) >>> for j in range(2 N_max 1): ... is_prime[2*j::j] = False

  • 浏览help(np.nonzero)并打印质数
  • 跟进:
    • 将上面的代码移动到一个名为的脚本文件中 prime_sieve.py
    • 运行它以检查它是否有效
    • 使用Eratosthenes 筛中建议的优化:
  • 跳过j那些已经知道不是素数的
  • 第一个划掉的数字是

1.1.7. 花式索引

NumPy 数组可以用切片索引,也可以用布尔或整数数组(掩码)索引。这种方法称为花式索引。它创建副本而不是查看

使用布尔掩码

>>> >>> np.random.seed(3) >>> a = np.random.randint(0 21 15) >>> a array([10 3 8 0 19 10 11 9 10 6 0 20 12 7 14]) >>> (a % 3 == 0) array([False True False True False False False True False True True False True False False]) >>> mask = (a % 3 == 0) >>> extract_from_a = a[mask] # or a[a%3==0] >>> extract_from_a # extract a sub-array with the mask array([ 3 0 9 6 0 12])

使用掩码进行索引对于为子数组分配新值非常有用:

>>> >>> a[a % 3 == 0] = -1 >>> a array([10 -1 8 -1 19 10 11 -1 10 -1 -1 20 -1 7 14])

用整数数组索引

>>> >>> a = np.arange(0 100 10) >>> a array([ 0 10 20 30 40 50 60 70 80 90])

可以使用整数数组进行索引,其中相同的索引重复多次:

>>> >>> a[[2 3 2 4 2]] # note: [2 3 2 4 2] is a Python list array([20 30 20 40 20])

可以使用这种索引分配新值:

>>> >>> a[[9 7]] = -100 >>> a array([ 0 10 20 30 40 50 60 -100 80 -100])

当通过使用整数数组索引创建新数组时,新数组具有与整数数组相同的形状:

>>> >>> a = np.arange(10) >>> idx = np.array([[3 4] [9 7]]) >>> idx.shape (2 2) >>> a[idx] array([[3 4] [9 7]])

下图说明了各种花哨的索引语法

python使用numpy求数组最大值(用Python做科学计算工具篇)(7)

练习:花式索引

  • 再次,重现上图中显示的花哨索引。
  • 使用左侧的花哨索引和右侧的数组创建将值分配到数组中,例如通过将上图中的数组部分设置为零。

猜您喜欢: