用 NumPy 在 Python 中处理数字

时间:2022-01-13 14:07来源:http://www.shopwholesalejerseys.com 作者:13岁这水水逼太嫩了-这水水逼太嫩了-19岁又紧水又多 点击:
兼职招募 | 51CTO社区编辑添盟指南

这篇文章商议了装配 NumPy,然后创建、读取和排序 NumPy 数组。

NumPy(即 Numerical Python)是一个库,它使得在 Python 中对线性数列和矩阵进走统计和荟萃操作变得容易。吾在 Python 数据类型的笔记中介绍过,它比 Python 的列外快几个数目级。NumPy 在数据分析和科学计算中行使得相等屡次。

吾将介绍装配 NumPy,然后创建、读取和排序 NumPy 数组。NumPy 数组也被称为 ndarray,即 N 维数组的缩写。

装配 NumPy

行使 pip 装配 NumPy 包专门浅易,能够像装配其他柔件包相通进走装配:

pip install numpy

装配了 NumPy 包后,只需将其导入你的 Python 文件中:

import numpy as np

将 numpy 以 np 之名导入是一个标准的通例,但你能够不行使 np,而是行使你想要的任何其他又名。

为什么行使 NumPy? 由于它比 Python 列外要快益几个数目级

当涉及到处理大量的数值时,NumPy 比清淡的 Python 列外快几个数目级。为了望望它到底有众快,吾最先测量在清淡 Python 列外上进走 min() 和 max() 操作的时间。

吾将最先创建一个具有 999,999,999 项的 Python 列外:

>>> my_list = range(1, 1000000000)>>> len(my_list)999999999

现在吾将测量在这个列外中找到最幼值的时间:

>>> start = time.time()>>> min(my_list)1>>> print('Time elapsed in milliseconds: ' + str((time.time() - start) * 1000))Time elapsed in milliseconds: 27007.00879096985

这花了大约 27,007 毫秒,也就是大约 27 秒。这是个很长的时间。现在吾试着找出追求最大值的时间:

>>> start = time.time()>>> max(my_list)999999999>>> print('Time elapsed in milliseconds: ' + str((time.time() - start) * 1000))Time elapsed in milliseconds: 28111.071348190308

这花了大约 28,111 毫秒,也就是大约 28 秒。

现在吾试试用 NumPy 找到最幼值和最大值的时间:

>>> my_list = np.arange(1, 1000000000)>>> len(my_list)999999999>>> start = time.time()>>> my_list.min()1>>> print('Time elapsed in milliseconds: ' + str((time.time() - start) * 1000))Time elapsed in milliseconds: 1151.1778831481934>>>>>> start = time.time()>>> my_list.max()999999999>>> print('Time elapsed in milliseconds: ' + str((time.time() - start) * 1000))Time elapsed in milliseconds: 1114.8970127105713

找到最幼值花了大约 1151 毫秒,找到最大值 1114 毫秒。这大约是 1 秒。

正如你所望到的,行使 NumPy 能够将追求一个大约有 10 亿个值的列外的最幼值和最大值的时间 从大约 28 秒缩短到 1 秒。这就是 NumPy 的兴旺之处。

行使 Python 列外创建 ndarray

有几栽手段能够在 NumPy 中创建 ndarray。

你能够始末行使元素列外来创建一个 ndarray:

>>> my_ndarray = np.array([1, 2, 3, 4, 5])>>> print(my_ndarray)[1 2 3 4 5]

有了上面的 ndarray 定义,吾将检查几件事。最先,上面定义的变量的类型是 numpy.ndarray。这是一切 NumPy ndarray 的类型:

>>> type(my_ndarray)<class 'numpy.ndarray'>

这边要仔细的另一件事是 “形状shape”。ndarray 的形状是 ndarray 的每个维度的长度。你能够望到,my_ndarray 的形状是 (5,)。这意味着 my_ndarray 包含一个有 5 个元素的维度(轴)。

>>> np.shape(my_ndarray)(5,)

数组中的维数被称为它的 “秩rank”。因而上面的 ndarray 的秩是 1。

吾将定义另一个 ndarray my_ndarray2 行为一个众维 ndarray。那么它的形状会是什么呢?请望下面:

>>> my_ndarray2 = np.array([(1, 2, 3), (4, 5, 6)])>>> np.shape(my_ndarray2)(2, 3)

这是一个秩为 2 的 ndarray。另一个要检查的属性是 dtype,也就是数据类型。检查吾们的 ndarray 的 dtype 能够得到以下终局:

>>> my_ndarray.dtypedtype('int64')

int64 意味着吾们的 ndarray 是由 64 位整数构成的。NumPy 不克创建同化类型的 ndarray,必须只包含一栽类型的元素。倘若你定义了一个包含同化元素类型的 ndarray,NumPy 会自动将一切的元素类型转换为能够包含一切元素的最高元素类型。

例如,创建一个 int 和 float 的同化序列将创建一个 float64 的 ndarray:

>>> my_ndarray2 = np.array([1, 2.0, 3])>>> print(my_ndarray2)[1. 2. 3.]>>> my_ndarray2.dtypedtype('float64')

另外,将其中一个元素竖立为 string 将创建 dtype 等于 <U21 的字符串 ndarray,意味着吾们的 ndarray 包含 unicode 字符串:

>>> my_ndarray2 = np.array([1, '2', 3])>>> print(my_ndarray2)['1' '2' '3']>>> my_ndarray2.dtypedtype('<U21')

size 属性将表现吾们的 ndarray 中存在的元素总数:

>>> my_ndarray = np.array([1, 2, 3, 4, 5])>>> my_ndarray.size5
行使 NumPy 手段创建 ndarray

倘若你不想直接行使列外来创建 ndarray,还有几栽能够用来创建它的 NumPy 手段。

你能够行使 np.zeros() 来创建一个填满 0 的 ndarray。它必要一个“形状”行为参数,这是一个包含走数和列数的列外。它还能够批准一个可选的 dtype 参数,这是 ndarray 的数据类型:

>>> my_ndarray = np.zeros([2,3], dtype=int)>>> print(my_ndarray)[[0 0 0] [0 0 0]]

你能够行使 np. ones() 来创建一个填满 1 的 ndarray:

>>> my_ndarray = np.ones([2,3], dtype=int)>>> print(my_ndarray)[[1 1 1] [1 1 1]]

你能够行使 np.full() 来给 ndarray 填充一个特定的值:

>>> my_ndarray = np.full([2,3], 10, dtype=int)>>> print(my_ndarray)[[10 10 10] [10 10 10]]

你能够行使 np.eye() 来创建一个单位矩阵 / ndarray,这是一个沿主对角线都是 1 的正方形矩阵。正方形矩阵是一个走数和列数相通的矩阵:

>>> my_ndarray = np.eye(3, dtype=int)>>> print(my_ndarray)[[1 0 0] [0 1 0] [0 0 1]]

你能够行使 np.diag() 来创建一个沿对角线有指定数值的矩阵,而在矩阵的其他片面为 0:

>>> my_ndarray = np.diag([10, 20, 30, 40, 50])>>> print(my_ndarray)[[10  0  0  0  0] [ 0 20  0  0  0] [ 0  0 30  0  0] [ 0  0  0 40  0] [ 0  0  0  0 50]]

你能够行使 np.range() 来创建一个具有特定数值周围的 ndarray。它是始末指定一个整数的开起和终结(不包括)周围以及一个步长来创建的:

>>> my_ndarray = np.arange(1, 20, 3)>>> print(my_ndarray)[ 1  4  7 10 13 16 19]
读取 ndarray

ndarray 的值能够行使索引、分片或布尔索引来读取。

行使索引读取 ndarray 的值

在索引中,你能够行使 ndarray 的元素的整数索引来读取数值,就像你读取 Python 列外相通。就像 Python 列外相通,索引从 0 开起。

例如,在定义如下的 ndarray 中:

>>> my_ndarray = np.arange(1, 20, 3)

第四个值将是 my_ndarray[3],即 10。末了一个值是 my_ndarray[-1],即 19:

>>> my_ndarray = np.arange(1, 20, 3)>>> print(my_ndarray[0])1>>> print(my_ndarray[3])10>>> print(my_ndarray[-1])19>>> print(my_ndarray[5])16>>> print(my_ndarray[6])19
行使分片读取 ndarray

你也能够行使分片来读取 ndarray 的块。分片的做事手段是用冒号(:)操作符指定一个开起索引和一个终结索引。然后,Python 将获取该开起和终结索引之间的 ndarray 片断:

>>> print(my_ndarray[:])[ 1  4  7 10 13 16 19]>>> print(my_ndarray[2:4])[ 7 10]>>> print(my_ndarray[5:6])[16]>>> print(my_ndarray[6:7])[19]>>> print(my_ndarray[:-1])[ 1  4  7 10 13 16]>>> print(my_ndarray[-1:])[19]

分片创建了一个 ndarray 的引用(或视图)。这意味着,修改分片中的值也会转折原起 ndarray 的值。

比如说:

>>> my_ndarray[-1:] = 100>>> print(my_ndarray)[  1   4   7  10  13  16 100]

对于秩超过 1 的 ndarray 的分片,能够行使 [走开起索引:走终结索引, 列开起索引:列终结索引] 语法:

>>> my_ndarray2 = np.array([(1, 2, 3), (4, 5, 6)])>>> print(my_ndarray2)[[1 2 3] [4 5 6]]>>> print(my_ndarray2[0:2,1:3])[[2 3] [5 6]]
行使布尔索引读取 ndarray 的手段

读取 ndarray 的另一栽手段是行使布尔索引。在这栽手段中,你在方括号内指定一个过滤条件,然后返回相符该条件的 ndarray 的一个片面。

例如,为了获得一个 ndarray 中一切大于 5 的值,你能够指定布尔索引操作 my_ndarray[my_ndarray > 5]。这个操作将返回一个包含一切大于 5 的值的 ndarray:

>>> my_ndarray = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])>>> my_ndarray2 = my_ndarray[my_ndarray > 5]>>> print(my_ndarray2)[ 6  7  8  9 10]

例如,为了获得一个 ndarray 中的一切偶数值,你能够行使如下的布尔索引操作:

>>> my_ndarray2 = my_ndarray[my_ndarray % 2 == 0]>>> print(my_ndarray2)[ 2  4  6  8 10]

而要得到一切的奇数值,你能够用这个手段:

>>> my_ndarray2 = my_ndarray[my_ndarray % 2 == 1]>>> print(my_ndarray2)[1 3 5 7 9]
ndarray 的矢量和标量算术

NumPy 的 ndarray 批准进走矢量和标量算术操作。在矢量算术中,在两个 ndarray 之间进走一个元素的算术操作。在标量算术中,算术运算是在一个 ndarray 和一个常数标量值之间进走的。

如下的两个 ndarray:

>>> my_ndarray = np.array([1, 2, 3, 4, 5])>>> my_ndarray2 = np.array([6, 7, 8, 9, 10])

倘若你将上述两个 ndarray 相添,就会产生一个两个 ndarray 的元素相添的新的 ndarray。例如,产生的 ndarray 的第一个元素将是原起 ndarray 的第一个元素相添的终局,以此类推:

>>> print(my_ndarray2 + my_ndarray)[ 7  9 11 13 15]

这边,7 是 1 和 6 的和,这是吾相添的 ndarray 中的前两个元素。同样,15 是 5 和10 之和,是末了一个元素。

请望以下算术运算:

>>> print(my_ndarray2 - my_ndarray)[5 5 5 5 5]>>>>>> print(my_ndarray2 * my_ndarray)[ 6 14 24 36 50]>>>>>> print(my_ndarray2 / my_ndarray)[6.         3.5        2.66666667 2.25       2.        ]

在 ndarray 中添一个标量值也有相通的成绩,标量值被增补到 ndarray 的一切元素中。这被称为“广播broadcasting”:

>>> print(my_ndarray + 10)[11 12 13 14 15]>>>>>> print(my_ndarray - 10)[-9 -8 -7 -6 -5]>>>>>> print(my_ndarray * 10)[10 20 30 40 50]>>>>>> print(my_ndarray / 10)[0.1 0.2 0.3 0.4 0.5]
ndarray 的排序

有两栽手段能够对 ndarray 进走原地或非原地排序。原地排序会对原起 ndarray 进走排序和修改,而非原地排序会返回排序后的 ndarray,但不会修改原起 ndarray。吾将尝试这两个例子:

>>> my_ndarray = np.array([3, 1, 2, 5, 4])>>> my_ndarray.sort()>>> print(my_ndarray)[1 2 3 4 5]

正如你所望到的,sort() 手段对 ndarray 进走原地排序,并修改了原数组。

还有一个手段叫 np.sort(),它对数组进走非原地排序:

>>> my_ndarray = np.array([3, 1, 2, 5, 4])>>> print(np.sort(my_ndarray))[1 2 3 4 5]>>> print(my_ndarray)[3 1 2 5 4]

正如你所望到的,np.sort() 手段返回一个已排序的 ndarray,但异国修改它。

总结

吾已经介绍了许众关于 NumPy 和 ndarray 的内容。吾谈到了创建 ndarray,读取它们的差别手段,基本的向量和标量算术,以及排序。NumPy 还有许众东西能够追求,包括像 union() 和 intersection()如许的荟萃操作,像 min() 和 max() 如许的统计操作,等等。

吾期待吾上面演示的例子是有用的。祝你在追求 NumPy 时喜悦。

鸿蒙官方战略配相符共建——HarmonyOS技术社区

网站分类
相关内容
热点内容
相关站点
友情链接
返回顶部