网易首页 > 网易号 > 正文 申请入驻

用 NumPy 在 Python 中处理数字 | Linux 中国

0
分享至

导读:这篇文章讨论了安装 NumPy,然后创建、读取和排序 NumPy 数组。                   

本文字数:9013,阅读时长大约: 11分钟

https://linux.cn/article-14160-1.html
作者:Ayush Sharma
译者:Xingyu.Wang

NumPy(即 Numerical Python)是一个库,它使得在 Python 中对线性数列和矩阵进行统计和集合操作变得容易。 notes.ayushsharma.in,它比 Python 的列表快几个数量级。NumPy 在数据分析和科学计算中使用得相当频繁。

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

安装 NumPy

使用 pip 安装 NumPy 包非常简单,可以像安装其他软件包一样进行安装:

  1. pip install numpy

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

  1. import numpy as np

numpynp 之名导入是一个标准的惯例,但你可以不使用 np,而是使用你想要的任何其他别名。

为什么使用 NumPy? 因为它比 Python 列表要快好几个数量级

当涉及到处理大量的数值时,NumPy 比普通的 Python 列表快几个数量级。为了看看它到底有多快,我首先测量在普通 Python 列表上进行 min()max() 操作的时间。

我将首先创建一个具有 999,999,999 项的 Python 列表:

  1. >>> my_list = range(1, 1000000000)

  2. >>> len(my_list)

  3. 999999999

现在我将测量在这个列表中找到最小值的时间:

  1. >>> start = time.time()

  2. >>> min(my_list)

  3. 1

  4. >>> print('Time elapsed in milliseconds: ' + str((time.time() - start) * 1000))

  5. Time elapsed in milliseconds: 27007.00879096985

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

  1. >>> start = time.time()

  2. >>> max(my_list)

  3. 999999999

  4. >>> print('Time elapsed in milliseconds: ' + str((time.time() - start) * 1000))

  5. Time elapsed in milliseconds: 28111.071348190308

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

现在我试试用 NumPy 找到最小值和最大值的时间:

  1. >>> my_list = np.arange(1, 1000000000)

  2. >>> len(my_list)

  3. 999999999

  4. >>> start = time.time()

  5. >>> my_list.min()

  6. 1

  7. >>> print('Time elapsed in milliseconds: ' + str((time.time() - start) * 1000))

  8. Time elapsed in milliseconds: 1151.1778831481934

  9. >>>

  10. >>> start = time.time()

  11. >>> my_list.max()

  12. 999999999

  13. >>> print('Time elapsed in milliseconds: ' + str((time.time() - start) * 1000))

  14. Time elapsed in milliseconds: 1114.8970127105713

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

正如你所看到的,使用 NumPy 可以将寻找一个大约有 10 亿个值的列表的最小值和最大值的时间 从大约 28 秒减少到 1 秒。这就是 NumPy 的强大之处。

使用 Python 列表创建 ndarray

有几种方法可以在 NumPy 中创建 ndarray。

你可以通过使用元素列表来创建一个 ndarray:

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

  2. >>> print(my_ndarray)

  3. [1 2 3 4 5]

有了上面的 ndarray 定义,我将检查几件事。首先,上面定义的变量的类型是 numpy.ndarray。这是所有 NumPy ndarray 的类型:

  1. >>> type(my_ndarray)

这里要注意的另一件事是 “形状(shape)”。ndarray 的形状是 ndarray 的每个维度的长度。你可以看到,my_ndarray 的形状是 (5,)。这意味着 my_ndarray 包含一个有 5 个元素的维度(轴)。

  1. >>> np.shape(my_ndarray)

  2. (5,)

数组中的维数被称为它的 “秩(rank)”。所以上面的 ndarray 的秩是 1。

我将定义另一个 ndarray my_ndarray2 作为一个多维 ndarray。那么它的形状会是什么呢?请看下面:

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

  2. >>> np.shape(my_ndarray2)

  3. (2, 3)

这是一个秩为 2 的 ndarray。另一个要检查的属性是 dtype,也就是数据类型。检查我们的 ndarray 的 dtype 可以得到以下结果:

  1. >>> my_ndarray.dtype

  2. dtype('int64')

int64 意味着我们的 ndarray 是由 64 位整数组成的。NumPy 不能创建混合类型的 ndarray,必须只包含一种类型的元素。如果你定义了一个包含混合元素类型的 ndarray,NumPy 会自动将所有的元素类型转换为可以包含所有元素的最高元素类型。

例如,创建一个 intfloat 的混合序列将创建一个 float64 的 ndarray:

  1. >>> my_ndarray2 = np.array([1, 2.0, 3])

  2. >>> print(my_ndarray2)

  3. [1. 2. 3.]

  4. >>> my_ndarray2.dtype

  5. dtype('float64')

另外,将其中一个元素设置为 string 将创建 dtype 等于 的字符串 ndarray,意味着我们的 ndarray 包含 unicode 字符串:

  1. >>> my_ndarray2 = np.array([1, '2', 3])

  2. >>> print(my_ndarray2)

  3. ['1' '2' '3']

  4. >>> my_ndarray2.dtype

  5. dtype(')

size 属性将显示我们的 ndarray 中存在的元素总数:

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

  2. >>> my_ndarray.size

  3. 5

使用 NumPy 方法创建 ndarray

如果你不想直接使用列表来创建 ndarray,还有几种可以用来创建它的 NumPy 方法。

你可以使用 np.zeros() 来创建一个填满 0 的 ndarray。它需要一个“形状”作为参数,这是一个包含行数和列数的列表。它还可以接受一个可选的 dtype 参数,这是 ndarray 的数据类型:

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

  2. >>> print(my_ndarray)

  3. [[0 0 0]

  4. [0 0 0]]

你可以使用 np. ones() 来创建一个填满 1 的 ndarray:

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

  2. >>> print(my_ndarray)

  3. [[1 1 1]

  4. [1 1 1]]

你可以使用 np.full() 来给 ndarray 填充一个特定的值:

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

  2. >>> print(my_ndarray)

  3. [[10 10 10]

  4. [10 10 10]]

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

  1. >>> my_ndarray = np.eye(3, dtype=int)

  2. >>> print(my_ndarray)

  3. [[1 0 0]

  4. [0 1 0]

  5. [0 0 1]]

你可以使用 np.diag() 来创建一个沿对角线有指定数值的矩阵,而在矩阵的其他部分为 0

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

  2. >>> print(my_ndarray)

  3. [[10 0 0 0 0]

  4. [ 0 20 0 0 0]

  5. [ 0 0 30 0 0]

  6. [ 0 0 0 40 0]

  7. [ 0 0 0 0 50]]

你可以使用 np.range() 来创建一个具有特定数值范围的 ndarray。它是通过指定一个整数的开始和结束(不包括)范围以及一个步长来创建的:

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

  2. >>> print(my_ndarray)

  3. [ 1 4 7 10 13 16 19]

读取 ndarray

ndarray 的值可以使用索引、分片或布尔索引来读取。

使用索引读取 ndarray 的值

在索引中,你可以使用 ndarray 的元素的整数索引来读取数值,就像你读取 Python 列表一样。就像 Python 列表一样,索引从 0 开始。

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

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

第四个值将是 my_ndarray[3],即 10。最后一个值是 my_ndarray[-1],即 19

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

  2. >>> print(my_ndarray[0])

  3. 1

  4. >>> print(my_ndarray[3])

  5. 10

  6. >>> print(my_ndarray[-1])

  7. 19

  8. >>> print(my_ndarray[5])

  9. 16

  10. >>> print(my_ndarray[6])

  11. 19

使用分片读取 ndarray

你也可以使用分片来读取 ndarray 的块。分片的工作方式是用冒号(:)操作符指定一个开始索引和一个结束索引。然后,Python 将获取该开始和结束索引之间的 ndarray 片断:

  1. >>> print(my_ndarray[:])

  2. [ 1 4 7 10 13 16 19]

  3. >>> print(my_ndarray[2:4])

  4. [ 7 10]

  5. >>> print(my_ndarray[5:6])

  6. [16]

  7. >>> print(my_ndarray[6:7])

  8. [19]

  9. >>> print(my_ndarray[:-1])

  10. [ 1 4 7 10 13 16]

  11. >>> print(my_ndarray[-1:])

  12. [19]

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

比如说:

  1. >>> my_ndarray[-1:] = 100

  2. >>> print(my_ndarray)

  3. [ 1 4 7 10 13 16 100]

对于秩超过 1 的 ndarray 的分片,可以使用 [行开始索引:行结束索引, 列开始索引:列结束索引] 语法:

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

  2. >>> print(my_ndarray2)

  3. [[1 2 3]

  4. [4 5 6]]

  5. >>> print(my_ndarray2[0:2,1:3])

  6. [[2 3]

  7. [5 6]]

使用布尔索引读取 ndarray 的方法

读取 ndarray 的另一种方法是使用布尔索引。在这种方法中,你在方括号内指定一个过滤条件,然后返回符合该条件的 ndarray 的一个部分。

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

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

  2. >>> my_ndarray2 = my_ndarray[my_ndarray > 5]

  3. >>> print(my_ndarray2)

  4. [ 6 7 8 9 10]

例如,为了获得一个 ndarray 中的所有偶数值,你可以使用如下的布尔索引操作:

  1. >>> my_ndarray2 = my_ndarray[my_ndarray % 2 == 0]

  2. >>> print(my_ndarray2)

  3. [ 2 4 6 8 10]

而要得到所有的奇数值,你可以用这个方法:

  1. >>> my_ndarray2 = my_ndarray[my_ndarray % 2 == 1]

  2. >>> print(my_ndarray2)

  3. [1 3 5 7 9]

ndarray 的矢量和标量算术

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

如下的两个 ndarray:

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

  2. >>> my_ndarray2 = np.array([6, 7, 8, 9, 10])

如果你将上述两个 ndarray 相加,就会产生一个两个 ndarray 的元素相加的新的 ndarray。例如,产生的 ndarray 的第一个元素将是原始 ndarray 的第一个元素相加的结果,以此类推:

  1. >>> print(my_ndarray2 + my_ndarray)

  2. [ 7 9 11 13 15]

这里,716 的和,这是我相加的 ndarray 中的前两个元素。同样,15510 之和,是最后一个元素。

请看以下算术运算:

  1. >>> print(my_ndarray2 - my_ndarray)

  2. [5 5 5 5 5]

  3. >>>

  4. >>> print(my_ndarray2 * my_ndarray)

  5. [ 6 14 24 36 50]

  6. >>>

  7. >>> print(my_ndarray2 / my_ndarray)

  8. [6. 3.5 2.66666667 2.25 2. ]

在 ndarray 中加一个标量值也有类似的效果,标量值被添加到 ndarray 的所有元素中。这被称为“广播(broadcasting)”:

  1. >>> print(my_ndarray + 10)

  2. [11 12 13 14 15]

  3. >>>

  4. >>> print(my_ndarray - 10)

  5. [-9 -8 -7 -6 -5]

  6. >>>

  7. >>> print(my_ndarray * 10)

  8. [10 20 30 40 50]

  9. >>>

  10. >>> print(my_ndarray / 10)

  11. [0.1 0.2 0.3 0.4 0.5]

ndarray 的排序

有两种方法可以对 ndarray 进行原地或非原地排序。原地排序会对原始 ndarray 进行排序和修改,而非原地排序会返回排序后的 ndarray,但不会修改原始 ndarray。我将尝试这两个例子:

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

  2. >>> my_ndarray.sort()

  3. >>> print(my_ndarray)

  4. [1 2 3 4 5]

正如你所看到的,sort() 方法对 ndarray 进行原地排序,并修改了原数组。

还有一个方法叫 np.sort(),它对数组进行非原地排序:

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

  2. >>> print(np.sort(my_ndarray))

  3. [1 2 3 4 5]

  4. >>> print(my_ndarray)

  5. [3 1 2 5 4]

正如你所看到的,np.sort() 方法返回一个已排序的 ndarray,但没有修改它。

总结

我已经介绍了很多关于 NumPy 和 ndarray 的内容。我谈到了创建 ndarray,读取它们的不同方法,基本的向量和标量算术,以及排序。NumPy 还有很多东西可以探索,包括像 union()intersection()这样的集合操作,像 min()max() 这样的统计操作,等等。

我希望我上面演示的例子是有用的。祝你在探索 NumPy 时愉快。

本文最初发表于 notes.ayushsharma.in,经授权后改编。

via:

作者: 选题: 译者: 校对:

本文由 原创编译, 荣誉推出

欢迎遵照 CC-BY-NC-SA 协议规定转载,

如需转载,请在文章下留言 “ 转载:公众号名称”,

我们将为您添加白名单,授权“ 转载文章时可以修改”。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
46岁董洁花期太短了,这是董洁为某时尚杂志拍的大片,董洁贴上假胡子,脸上戴着厚重的网纱,脖子上挂着繁复的花朵,这妆造真的太前卫了

46岁董洁花期太短了,这是董洁为某时尚杂志拍的大片,董洁贴上假胡子,脸上戴着厚重的网纱,脖子上挂着繁复的花朵,这妆造真的太前卫了

牛油果生活观
2026-06-02 19:09:43
退休国企干部、公职人员起诉离婚,庭审互揭老底牵出巨额财产线索;法院:涉嫌犯罪,移送公安、纪检监察

退休国企干部、公职人员起诉离婚,庭审互揭老底牵出巨额财产线索;法院:涉嫌犯罪,移送公安、纪检监察

大风新闻
2026-06-03 19:48:17
不到24小时,美国接连迎来三大坏消息,内部实情已被曝光

不到24小时,美国接连迎来三大坏消息,内部实情已被曝光

策前论
2026-06-03 14:52:30
割四赔五后续:麦客撤了,麦烂了,农户跪了,这锅谁背?

割四赔五后续:麦客撤了,麦烂了,农户跪了,这锅谁背?

番外行
2026-06-02 14:19:47
为什么现在外敌越来越不怕中国?著名军事专家戴旭曾一针见血

为什么现在外敌越来越不怕中国?著名军事专家戴旭曾一针见血

叹为观止易
2026-06-03 05:36:51
继续黑马之旅!淘汰郑钦文之人横扫22号种子,首进大满贯四强

继续黑马之旅!淘汰郑钦文之人横扫22号种子,首进大满贯四强

全景体育V
2026-06-03 19:09:08
今年高考很平静:只有985、211找得到好工作,其他80%都是销售相关工作

今年高考很平静:只有985、211找得到好工作,其他80%都是销售相关工作

老郭在学习
2026-06-03 13:31:11
苹果5款新品官宣,6月9日,正式发布

苹果5款新品官宣,6月9日,正式发布

科技堡垒
2026-06-03 09:40:13
霍尔木兹大消息,美军宣布:“林肯”号航母参与封锁,战机空袭开往伊朗哈尔克岛油轮,致机舱起火!国际油价上涨,特朗普:尽快达成协议

霍尔木兹大消息,美军宣布:“林肯”号航母参与封锁,战机空袭开往伊朗哈尔克岛油轮,致机舱起火!国际油价上涨,特朗普:尽快达成协议

每日经济新闻
2026-06-03 07:49:10
王守业贪污1.6亿,2005年“双规”后却被放出,他叫嚣:我摆平了

王守业贪污1.6亿,2005年“双规”后却被放出,他叫嚣:我摆平了

帝哥说史
2026-06-02 21:40:03
四川巴中一小学为教师定制1500元一套的西装,官方通报:存在决策程序失当、经费使用不规范等问题,校长马某某停职

四川巴中一小学为教师定制1500元一套的西装,官方通报:存在决策程序失当、经费使用不规范等问题,校长马某某停职

扬子晚报
2026-06-03 07:22:58
钟景辉,今日在睡梦中离世

钟景辉,今日在睡梦中离世

最江阴
2026-06-03 14:08:54
妻子穿几十元T恤,丈夫满身名牌做医美车内常备上万现金,却不愿出2500生活费!遭多年家暴,女子起诉离婚,发现1400万元已被转走

妻子穿几十元T恤,丈夫满身名牌做医美车内常备上万现金,却不愿出2500生活费!遭多年家暴,女子起诉离婚,发现1400万元已被转走

华商网
2026-06-03 17:03:16
2026届高考生,为何被称作近十年最尴尬一届?真实现状太扎心

2026届高考生,为何被称作近十年最尴尬一届?真实现状太扎心

老特有话说
2026-06-03 15:07:06
特朗普称对伊朗海上封锁或持续至9月

特朗普称对伊朗海上封锁或持续至9月

新华社
2026-06-03 18:30:30
运动员哪能这么白这么露?铁三女神冯竟爽再次夺冠,回击流言蜚语

运动员哪能这么白这么露?铁三女神冯竟爽再次夺冠,回击流言蜚语

杨华评论
2026-06-03 02:20:48
放不下的顿巴斯,回不去的体面

放不下的顿巴斯,回不去的体面

秋月独朗
2026-06-03 14:14:30
昨天面试了一个前台,37岁,是个宝妈。她工资要的很低,说2500就可以,但有个条件,9点来上班,正常是8点。没想到老板拒绝了

昨天面试了一个前台,37岁,是个宝妈。她工资要的很低,说2500就可以,但有个条件,9点来上班,正常是8点。没想到老板拒绝了

背包旅行
2026-06-03 17:26:49
难堪大任!王楚钦任国乒队长不到36小时,乒协主席王励勤受到牵连

难堪大任!王楚钦任国乒队长不到36小时,乒协主席王励勤受到牵连

削桐作琴
2026-06-03 16:23:15
月入130万,排队两小时!下沉市场真能接住漂亮饭?

月入130万,排队两小时!下沉市场真能接住漂亮饭?

红餐网
2026-06-03 12:08:10
2026-06-03 20:28:49
Linux
Linux
Linux 中国开源社区
8018文章数 73112关注度
往期回顾 全部

科技要闻

传DeepSeek融资意向500亿:腾讯投100亿

头条要闻

民警驾车致1死1残获刑1年2个月 女伤者刚试管有了胚胎

头条要闻

民警驾车致1死1残获刑1年2个月 女伤者刚试管有了胚胎

体育要闻

选择中国品牌的库里,和他们的巨大野心

娱乐要闻

官方痛批乱象 刘涛郑恺等艺人遭点名

财经要闻

AI,开始偷懒了?

汽车要闻

专访蒋平:安全不做高低配 长安要让安全技术普惠

态度原创

家居
亲子
房产
手机
军事航空

家居要闻

江畔轻奢 观云大宅

亲子要闻

“托举孩子进山姆”为何惹众怒?

房产要闻

突发!254亩调规,海口江东的超级学校真的快来了!

手机要闻

全能影像旗舰怎么选?vivo S60领衔四款中端机型横评

军事要闻

美伊互袭波及多国 过去一夜中东局势骤然升级

无障碍浏览 进入关怀版