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开发的小球完全弹性碰撞游戏代码
Oct 15 Python
Python计算已经过去多少个周末的方法
Jul 25 Python
Python语言描述机器学习之Logistic回归算法
Dec 21 Python
python数据分析数据标准化及离散化详解
Feb 26 Python
Python标准库使用OrderedDict类的实例讲解
Feb 14 Python
解决pycharm remote deployment 配置的问题
Jun 27 Python
Python3 Tkinkter + SQLite实现登录和注册界面
Nov 19 Python
Python如何使用Gitlab API实现批量的合并分支
Nov 27 Python
基于python的docx模块处理word和WPS的docx格式文件方式
Feb 13 Python
Python unittest单元测试框架实现参数化
Apr 29 Python
解决Keras 自定义层时遇到版本的问题
Jun 16 Python
Python 实现集合Set的示例
Dec 21 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
php xml 入门学习资料
2011/01/01 PHP
PHP字符串的编码问题的详细介绍
2013/04/27 PHP
PHP中遇到BOM、编码导致json_decode函数无法解析问题
2014/07/02 PHP
php中json_encode UTF-8中文乱码的更好解决方法
2014/09/28 PHP
PHP实现数组和对象的相互转换操作示例
2019/03/20 PHP
关于window.pageYOffset和document.documentElement.scrollTop
2011/04/05 Javascript
阻止子元素继承父元素事件具体思路及实现
2013/05/02 Javascript
js 使FORM表单的所有元素不可编辑的示例代码
2013/10/17 Javascript
javascript原生和jquery库实现iframe自适应高度和宽度
2014/07/18 Javascript
JavaScript中的类与实例实现方法
2015/01/23 Javascript
AngularJS 中的指令实践开发指南(一)
2016/03/20 Javascript
Boostrap模态窗口的学习小结
2016/03/28 Javascript
jquery-mobile表单的创建方法详解
2016/11/23 Javascript
JS按钮闪烁功能的实现代码
2017/07/21 Javascript
vue-video-player 通过自定义按钮组件实现全屏切换效果【推荐】
2018/08/29 Javascript
JavaScript遍历DOM元素的常见方式示例
2019/02/16 Javascript
React 组件渲染和更新的实现代码示例
2019/02/21 Javascript
layui实现下拉框三级联动
2019/07/26 Javascript
js实现窗口全屏示例详解
2019/09/17 Javascript
Vue+Element实现网页版个人简历系统(推荐)
2019/12/31 Javascript
vue从零实现一个消息通知组件的方法详解
2020/03/16 Javascript
[06:16]DOTA2守卫传承者——职业选手谈心路历程
2015/02/26 DOTA
Eclipse + Python 的安装与配置流程
2013/03/05 Python
Python实现抓取页面上链接的简单爬虫分享
2015/01/21 Python
Python基于OpenCV实现人脸检测并保存
2019/07/23 Python
pycharm实现在虚拟环境中引入别人的项目
2020/03/09 Python
python 用Matplotlib作图中有多个Y轴
2020/11/28 Python
Python如何实现Paramiko的二次封装
2021/01/30 Python
心得体会范文
2014/01/04 职场文书
文科毕业生自荐书范文
2014/04/17 职场文书
写求职信有哪些注意事项
2014/05/08 职场文书
好段摘抄大全(48句)
2019/08/08 职场文书
利用Python+OpenCV三步去除水印
2021/05/28 Python
pytorch 如何使用batch训练lstm网络
2021/05/28 Python
淡雅古典唯美少女娇媚宁静迷人写真
2022/03/21 杂记
彻底弄懂Python中的回调函数(callback)
2022/06/25 Python