Python如何实现大型数组运算(使用NumPy)


Posted in Python onJuly 24, 2020

问题

你需要在大数据集(比如数组或网格)上面执行计算。

解决方案

涉及到数组的重量级运算操作,可以使用NumPy库。NumPy的一个主要特征是它会给Python提供一个数组对象,相比标准的Python列表而已更适合用来做数学运算。下面是一个简单的小例子,向你展示标准列表对象和NumPy数组对象之间的差别:

>>> # Python lists
>>> x = [1, 2, 3, 4]
>>> y = [5, 6, 7, 8]
>>> x * 2
[1, 2, 3, 4, 1, 2, 3, 4]
>>> x + 10
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "int") to list
>>> x + y
[1, 2, 3, 4, 5, 6, 7, 8]

>>> # Numpy arrays
>>> import numpy as np
>>> ax = np.array([1, 2, 3, 4])
>>> ay = np.array([5, 6, 7, 8])
>>> ax * 2
array([2, 4, 6, 8])
>>> ax + 10
array([11, 12, 13, 14])
>>> ax + ay
array([ 6, 8, 10, 12])
>>> ax * ay
array([ 5, 12, 21, 32])
>>>

正如所见,两种方案中数组的基本数学运算结果并不相同。特别的,numpy中的标量运算(比如 ax * 2 或 ax + 10 )会作用在每一个元素上。另外,当两个操作数都是数组的时候执行元素对等位置计算,并最终生成一个新的数组。

对整个数组中所有元素同时执行数学运算可以使得作用在整个数组上的函数运算简单而又快速。比如,如果你想计算多项式的值,可以这样做:

>>> def f(x):
... return 3*x**2 - 2*x + 7
...
>>> f(ax)
array([ 8, 15, 28, 47])
>>>

NumPy还为数组操作提供了大量的通用函数,这些函数可以作为math模块中类似函数的替代。比如:

>>> np.sqrt(ax)
array([ 1. , 1.41421356, 1.73205081, 2. ])
>>> np.cos(ax)
array([ 0.54030231, -0.41614684, -0.9899925 , -0.65364362])
>>>

使用这些通用函数要比循环数组并使用math模块中的函数执行计算要快的多。因此,只要有可能的话尽量选择numpy的数组方案。

底层实现中,NumPy数组使用了C或者Fortran语言的机制分配内存。也就是说,它们是一个非常大的连续的并由同类型数据组成的内存区域。所以,你可以构造一个比普通Python列表大的多的数组。比如,如果你想构造一个10,000*10,000的浮点数二维网格,很轻松:

>>> grid = np.zeros(shape=(10000,10000), dtype=float)
>>> grid
  array([[ 0., 0., 0., ..., 0., 0., 0.],
  [ 0., 0., 0., ..., 0., 0., 0.],
  [ 0., 0., 0., ..., 0., 0., 0.],
  ...,
  [ 0., 0., 0., ..., 0., 0., 0.],
  [ 0., 0., 0., ..., 0., 0., 0.],
  [ 0., 0., 0., ..., 0., 0., 0.]])
>>>

所有的普通操作还是会同时作用在所有元素上:

>>> grid += 10
>>> grid
array([[ 10., 10., 10., ..., 10., 10., 10.],
  [ 10., 10., 10., ..., 10., 10., 10.],
  [ 10., 10., 10., ..., 10., 10., 10.],
  ...,
  [ 10., 10., 10., ..., 10., 10., 10.],
  [ 10., 10., 10., ..., 10., 10., 10.],
  [ 10., 10., 10., ..., 10., 10., 10.]])
>>> np.sin(grid)
array([[-0.54402111, -0.54402111, -0.54402111, ..., -0.54402111,
    -0.54402111, -0.54402111],
  [-0.54402111, -0.54402111, -0.54402111, ..., -0.54402111,
    -0.54402111, -0.54402111],
  [-0.54402111, -0.54402111, -0.54402111, ..., -0.54402111,
    -0.54402111, -0.54402111],
  ...,
  [-0.54402111, -0.54402111, -0.54402111, ..., -0.54402111,
    -0.54402111, -0.54402111],
  [-0.54402111, -0.54402111, -0.54402111, ..., -0.54402111,
    -0.54402111, -0.54402111],
  [-0.54402111, -0.54402111, -0.54402111, ..., -0.54402111,
    -0.54402111, -0.54402111]])
>>>

关于NumPy有一点需要特别的主意,那就是它扩展Python列表的索引功能 - 特别是对于多维数组。为了说明清楚,先构造一个简单的二维数组并试着做些试验:

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

>>> # Select row 1
>>> a[1]
array([5, 6, 7, 8])

>>> # Select column 1
>>> a[:,1]
array([ 2, 6, 10])

>>> # Select a subregion and change it
>>> a[1:3, 1:3]
array([[ 6, 7],
    [10, 11]])
>>> a[1:3, 1:3] += 10
>>> a
array([[ 1, 2, 3, 4],
    [ 5, 16, 17, 8],
    [ 9, 20, 21, 12]])

>>> # Broadcast a row vector across an operation on all rows
>>> a + [100, 101, 102, 103]
array([[101, 103, 105, 107],
    [105, 117, 119, 111],
    [109, 121, 123, 115]])
>>> a
array([[ 1, 2, 3, 4],
    [ 5, 16, 17, 8],
    [ 9, 20, 21, 12]])

>>> # Conditional assignment on an array
>>> np.where(a < 10, a, 10)
array([[ 1, 2, 3, 4],
    [ 5, 10, 10, 8],
    [ 9, 10, 10, 10]])
>>>

讨论

NumPy是Python领域中很多科学与工程库的基础,同时也是被广泛使用的最大最复杂的模块。即便如此,在刚开始的时候通过一些简单的例子和玩具程序也能帮我们完成一些有趣的事情。

通常我们导入NumPy模块的时候会使用语句 import numpy as np 。这样的话你就不用再你的程序里面一遍遍的敲入numpy,只需要输入np就行了,节省了不少时间。

如果想获取更多的信息,你当然得去NumPy官网逛逛了,网址是: http://www.numpy.org

以上就是Python如何实现大型数组运算(使用NumPy)的详细内容,更多关于Python 大型数组运算(使用NumPy)的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python使用点操作符访问字典(dict)数据的方法
Mar 16 Python
python pandas中DataFrame类型数据操作函数的方法
Apr 08 Python
利用Python写一个爬妹子的爬虫
Jun 08 Python
python3基于OpenCV实现证件照背景替换
Jul 18 Python
python 判断矩阵中每行非零个数的方法
Jan 26 Python
Python数据结构与算法(几种排序)小结
Jun 22 Python
Python二元赋值实用技巧解析
Oct 25 Python
Python合并2个字典成1个新字典的方法(9种)
Dec 19 Python
Python基于pygame实现单机版五子棋对战
Dec 26 Python
Django如何实现防止XSS攻击
Oct 13 Python
scrapy redis配置文件setting参数详解
Nov 18 Python
python_tkinter事件类型详情
Mar 20 Python
基于opencv的selenium滑动验证码的实现
Jul 24 #Python
详解python中GPU版本的opencv常用方法介绍
Jul 24 #Python
python定义类的简单用法
Jul 24 #Python
Python爬虫抓取指定网页图片代码实例
Jul 24 #Python
详解Flask前后端分离项目案例
Jul 24 #Python
通过实例了解Python异常处理机制底层实现
Jul 23 #Python
Python异常处理机制结构实例解析
Jul 23 #Python
You might like
DOM基础及php读取xml内容操作的方法
2015/01/23 PHP
前端必学之PHP语法基础
2016/01/01 PHP
Yii框架的redis命令使用方法简单示例
2019/10/15 PHP
php设计模式之观察者模式实例详解【星际争霸游戏案例】
2020/03/30 PHP
Prototype Date对象 学习
2009/07/12 Javascript
js数组操作学习总结
2013/11/04 Javascript
在jquery中combobox多选的不兼容问题总结
2013/12/24 Javascript
node.js实现BigPipe详解
2014/12/05 Javascript
微信小程序 Tab页切换更新数据
2017/01/05 Javascript
jQuery实现搜索页面关键字的功能
2017/02/16 Javascript
浅谈node的事件机制
2017/10/09 Javascript
vue2.0.js的多级联动选择器实现方法
2018/02/09 Javascript
微信小程序实现人脸识别
2018/05/25 Javascript
对angularjs框架下controller间的传值方法详解
2018/10/08 Javascript
layui之数据表格--与后台交互获取数据的方法
2019/09/29 Javascript
javascript设计模式 ? 备忘录模式原理与用法实例分析
2020/04/21 Javascript
最大K个数问题的Python版解法总结
2016/06/16 Python
Python算法应用实战之队列详解
2017/02/04 Python
分享几道你可能遇到的python面试题
2017/07/24 Python
Python图形绘制操作之正弦曲线实现方法分析
2017/12/25 Python
python PyTorch预训练示例
2018/02/11 Python
使用 Python 实现微信群友统计器的思路详解
2018/09/26 Python
使用Python实现微信提醒备忘录功能
2018/12/04 Python
利用Python正则表达式过滤敏感词的方法
2019/01/21 Python
Django异步任务之Celery的基本使用
2019/03/23 Python
python中的 zip函数详解及用法举例
2020/02/16 Python
canvas实现扭蛋机动画效果的示例代码
2018/10/17 HTML / CSS
个人优缺点自我评价
2014/01/27 职场文书
继承公证书
2014/04/09 职场文书
主题班会演讲稿
2014/05/22 职场文书
初中生毕业评语
2014/12/29 职场文书
开会迟到检讨书范文
2015/05/06 职场文书
世界文化遗产导游词
2019/08/07 职场文书
关于PHP数组迭代器的使用方法实例
2021/11/17 PHP
Nginx工作模式及代理配置的使用细节
2022/03/21 Servers
Vue深入理解插槽slot的使用
2022/08/05 Vue.js