Python科学计算包numpy用法实例详解


Posted in Python onFebruary 08, 2018

本文实例讲述了Python科学计算包numpy用法。分享给大家供大家参考,具体如下:

1 数据结构

numpy使用一种称为ndarray的类似Matlab的矩阵式数据结构管理数据,比python的列表和标准库的array类更为强大,处理数据更为方便。

1.1 数组的生成

在numpy中,生成数组需要指定数据类型,默认是int32,即整数,可以通过dtype参数来指定,一般用到的有int32boolfloat32uint32complex,分别代表整数、布尔值、浮点型、无符号整数和复数

一般而言,生成数组的方法有这么几种:

以list列表为参数生成(用tolist方法即可转换回list):

In[3]: a = array([1, 2, 3])
In[4]: a
Out[4]: array([1, 2, 3])
In[5]: a.tolist()
Out[5]: [1, 2, 3]

指定起点、终点和步长生成等差序列或等比数列:

In[7]: a = arange(1, 10, 2)
In[8]: a
Out[8]: array([1, 3, 5, 7, 9])
In[13]: a = linspace(0, 10, 5)
In[14]: a
Out[14]: array([ 0. ,  2.5,  5. ,  7.5, 10. ])
In[148]: a = logspace(0, 3, 10) # 0表示起点为10^0,3表示起点为10^3,基数通过base参数指定
In[149]: a
Out[148]: 
array([  1.    ,   2.15443469,   4.64158883,  10.    ,
     21.5443469 ,  46.41588834,  100.    ,  215.443469 ,
     464.15888336, 1000.    ])

从迭代器中生成:

In[17]: iter = (i for i in range(5))
In[18]: a = fromiter(iter, dtype=int32)
In[19]: a
Out[19]: array([0, 1, 2, 3, 4])

从函数中生成:

In[156]: def f(i, j):
...   return abs(i-j)
...   
In[157]: fromfunction(f, (4, 4))
Out[156]: 
array([[ 0., 1., 2., 3.],
    [ 1., 0., 1., 2.],
    [ 2., 1., 0., 1.],
    [ 3., 2., 1., 0.]])

还可以用zeros、ones、empty等函数快速创建数组。

矩阵视为二维数组:

In[24]: b = array([arange(5), arange(1, 6), arange(2, 7)])
In[25]: b
Out[25]: 
array([[0, 1, 2, 3, 4],
    [1, 2, 3, 4, 5],
    [2, 3, 4, 5, 6]])

根据相同的方法可以拓展到更高维。

另外,我们还可以生成自定义数据格式的数组(称为结构数组),用来记录电子表格或数据库中一行数据的信息:

In[61]: t = dtype([('name', str, 40), ('number', int32), ('score', float32)])
In[62]: t
Out[62]: dtype([('name', '<U40'), ('number', '<i4'), ('score', '<f4')])
In[63]: students = array([('Tom', 10, 80), ('Jenny', 11, 90.5), ('Mike', 9, 98.5)], dtype=t)
In[64]: students
Out[64]: 
array([('Tom', 10, 80.0), ('Jenny', 11, 90.5), ('Mike', 9, 98.5)], 
   dtype=[('name', '<U40'), ('number', '<i4'), ('score', '<f4')])
In[65]: students[1]
Out[65]: ('Jenny', 11, 90.5)

后面我们会看到pandas提供了一种更精致的方法处理记录。

1.2 数组的索引

简单的下标索引:

In[30]: a[2]
Out[30]: 2
In[31]: b[2, 1]
Out[31]: 3

与python一样,索引的起点为0。负数的索引当然也是可以的:

In[32]: a[-1]
Out[32]: 4
In[33]: b[-1, -2]
Out[33]: 5

以整数数组为下标索引,一次性索引多个值:

In[162]: arange(11, 20)[array([2, 4, 8])]
Out[161]: array([13, 15, 19])

还可以通过布尔值来索引:

In[40]: idx = array([True, False, False, True, True])
In[41]: a[idx]
Out[41]: array([0, 3, 4])

这可以应用在高级索引中,比如条件索引:

b[b>3]
Out[42]: array([4, 4, 5, 4, 5, 6])

得到b中所有大于3的元素,以array形式返回,我们能这么写的原因是b>3会返回一个布尔数组,形式与b一致,各位置的值是b中各元素与3比较之后的结果:

In[43]: b>3
Out[43]: 
array([[False, False, False, False, True],
    [False, False, False, True, True],
    [False, False, True, True, True]], dtype=bool)

1.3 数组的切片

ndarray数组支持各种形式的切片,既可以以下标为线索,还可以以值为线索,为了区分二者,重新生成一个数组:

a = arange(11, 20)
In[54]: a
Out[54]: array([11, 12, 13, 14, 15, 16, 17, 18, 19])

根据下标切片:

In[55]: a[1:4]
Out[55]: array([12, 13, 14])
In[56]: a[1:8:2]
Out[56]: array([12, 14, 16, 18])
In[57]: a[1::2]
Out[57]: array([12, 14, 16, 18])
In[58]: a[:8:]
Out[58]: array([11, 12, 13, 14, 15, 16, 17, 18])

方括号中三个参数为别是起点、终点和步长,默认值分别是0、-1、1,注意终点是不被包含的。可以简单地令步长为-1来翻转数组:

In[60]: a[::-1]
Out[60]: array([19, 18, 17, 16, 15, 14, 13, 12, 11])

ndarray也支持多维数组的切片,先生成一个三维数组,可以通过修改一维数组的shape属性或调用其reshape方法来生成:

In[68]: a = arange(0, 24).reshape(2, 3, 4)
In[69]: a
Out[69]: 
array([[[ 0, 1, 2, 3],
    [ 4, 5, 6, 7],
    [ 8, 9, 10, 11]],
    [[12, 13, 14, 15],
    [16, 17, 18, 19],
    [20, 21, 22, 23]]])

多维数组的索引其实跟一维区别不大,可以用:代表选取所有:

In[70]: a[:, 0, 0]
Out[70]: array([ 0, 12])
In[71]: a[0, :, 0]
Out[71]: array([0, 4, 8])
In[72]: a[0, 0, :]
Out[72]: array([0, 1, 2, 3])
In[73]: a[0, 0:2, 0:3]
Out[73]: 
array([[0, 1, 2],
    [4, 5, 6]])

多个冒号还可以用...来代替:

In[74]: a[...,3]
Out[74]: 
array([[ 3, 7, 11],
    [15, 19, 23]])

最后,可以使用slice对象来表示切片,它与用1:10:2形式产生切片类似:

In[169]: idx = slice(None, None, 2)
In[171]: a[idx,idx,idx]
Out[170]: 
array([[[ 0, 2],
    [ 8, 10]]])

相当于a[::2, ::2, ::2]

1.4 数组的变换

可以将上述三维数组展平:

In[75]: a.flatten()
Out[75]: 
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
    17, 18, 19, 20, 21, 22, 23])

转置:

In[77]: b.transpose()
Out[77]: 
array([[0, 1, 2],
    [1, 2, 3],
    [2, 3, 4],
    [3, 4, 5],
    [4, 5, 6]])

修改shape属性来改变维度:

In[79]: a.shape = 4, 6
In[80]: a
Out[80]: 
array([[ 0, 1, 2, 3, 4, 5],
    [ 6, 7, 8, 9, 10, 11],
    [12, 13, 14, 15, 16, 17],
    [18, 19, 20, 21, 22, 23]])

1.5 数组的组合

首先创建一个与a同大小的数组:

In[83]: b = 2*a

可以进行多种方式组合,如水平组合:

In[88]: hstack((a, b))
Out[88]: 
array([[ 0, 1, 2, 3, 4, 5, 0, 2, 4, 6, 8, 10],
    [ 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22],
    [12, 13, 14, 15, 16, 17, 24, 26, 28, 30, 32, 34],
    [18, 19, 20, 21, 22, 23, 36, 38, 40, 42, 44, 46]])

垂直组合:

In[89]: vstack((a, b))
Out[89]: 
array([[ 0, 1, 2, 3, 4, 5],
    [ 6, 7, 8, 9, 10, 11],
    [12, 13, 14, 15, 16, 17],
    [18, 19, 20, 21, 22, 23],
    [ 0, 2, 4, 6, 8, 10],
    [12, 14, 16, 18, 20, 22],
    [24, 26, 28, 30, 32, 34],
    [36, 38, 40, 42, 44, 46]])

用concatenate函数可以同时实现这两种方式,通过指定axis参数,默认为0,使用垂直组合。

还可以进行深度组合:

In[91]: dstack((a, b))
Out[91]: 
array([[[ 0, 0],
    [ 1, 2],
    [ 2, 4],
    [ 3, 6],
    [ 4, 8],
    [ 5, 10]],
    [[ 6, 12],
    [ 7, 14],
    [ 8, 16],
    [ 9, 18],
    [10, 20],
    [11, 22]],
    [[12, 24],
    [13, 26],
    [14, 28],
    [15, 30],
    [16, 32],
    [17, 34]],
    [[18, 36],
    [19, 38],
    [20, 40],
    [21, 42],
    [22, 44],
    [23, 46]]])

就好像将两张二维平面的点数据沿纵轴方向叠在一起一样。

1.6 数组的分割

水平分割:

In[94]: hsplit(a, 3)
Out[94]: 
[array([[ 0, 1],
    [ 6, 7],
    [12, 13],
    [18, 19]]), array([[ 2, 3],
    [ 8, 9],
    [14, 15],
    [20, 21]]), array([[ 4, 5],
    [10, 11],
    [16, 17],
    [22, 23]])]

垂直分割:

In[97]: vsplit(a, 2)
Out[96]: 
[array([[ 0, 1, 2, 3, 4, 5],
    [ 6, 7, 8, 9, 10, 11]]), array([[12, 13, 14, 15, 16, 17],
    [18, 19, 20, 21, 22, 23]])]

用split函数可以同时实现这两个效果,通过设置其axis参数区别。

类似地,可以通过函数dsplit进行深度分割。

另外可以使用ndarray的一些属性来查看数组的信息:

In[125]: a.ndim # 维数
Out[124]: 2
In[126]: a.size # 元素总个数
Out[125]: 24
In[127]: a.itemsize # 元素在内存中所占的字节
Out[126]: 4
In[128]: a.shape # 维度
Out[127]: (4, 6)
In[130]: a.T # 转置,相当于transponse函数
Out[129]: 
array([[ 0, 6, 12, 18],
    [ 1, 7, 13, 19],
    [ 2, 8, 14, 20],
    [ 3, 9, 15, 21],
    [ 4, 10, 16, 22],
    [ 5, 11, 17, 23]], dtype=int32)

另外多维数组的flat属性可以给出一个”扁平迭代器“——flatiter对象,使我们能像一维数组一样迭代高维数组:

In[134]: for item in array([1, 2, 3, 4]).reshape(2, 2).flat:
...   print(item)
...
1
2
3
4

flatiter对象可以直接获取多个元素,并直接赋值修改:

In[140]: af = a.flat
In[141]: af[:]
Out[140]: 
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
    17, 18, 19, 20, 21, 22, 23], dtype=int32)
In[143]: af[3] = 15
In[144]: af[:]
Out[143]: 
array([ 0, 1, 2, 15, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
    17, 18, 19, 20, 21, 22, 23], dtype=int32)

1.7 矩阵的生成

上面提到了可以用二维数组来模拟矩阵,其实,numpy专门提供了一种用于处理矩阵的数据结构——matrix,它通过mat函数构造生成:

In[8]: m = mat('1 2 3; 4 5 6; 7 8 9')
In[9]: m
Out[9]: 
matrix([[1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]])

二维数组与矩阵可以很方便地相互转换:

In[11]: array(m)
Out[11]: 
array([[1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]])
In[12]: mat(_)
Out[12]: 
matrix([[1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]])

用matrix来处理矩阵更方便,有更多方法以供使用,如:

求逆:

In[17]: m.I
Out[17]: 
matrix([[ -4.50359963e+15,  9.00719925e+15, -4.50359963e+15],
    [ 9.00719925e+15, -1.80143985e+16,  9.00719925e+15],
    [ -4.50359963e+15,  9.00719925e+15, -4.50359963e+15]])

分块矩阵:

In[25]: I = eye(3)
In[26]: bmat('m I; I m')
Out[26]: 
matrix([[ 1., 2., 3., 1., 0., 0.],
    [ 4., 5., 6., 0., 1., 0.],
    [ 7., 8., 9., 0., 0., 1.],
    [ 1., 0., 0., 1., 2., 3.],
    [ 0., 1., 0., 4., 5., 6.],
    [ 0., 0., 1., 7., 8., 9.]])

2 数据处理

2.1 条件判断和搜索

用where函数可以得到满足条件的索引,便于后期处理:

In[219]: a = arange(24).reshape(4, 6)
In[220]: where(a>8)
Out[219]: 
(array([1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3], dtype=int32),
 array([3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5], dtype=int32))

compress函数可以筛选出一维数组中满足条件的值:

In[28]: a[0, :].compress(a[0, :] > 2)
Out[28]: array([3, 4, 5])

2.2 CSV文件读写

CSV(逗号分割值)格式可以简单方便地保存数组或矩阵。相比于python的pickle方法,保存为CSV文件可以用一般文本编辑器随时打开查看。保存和读取CSV文件都很简单。

In[190]: b
Out[189]: 
array([[ 0, 2, 4, 6, 8, 10],
    [12, 14, 16, 18, 20, 22],
    [24, 26, 28, 30, 32, 34],
    [36, 38, 40, 42, 44, 46]])
In[191]: savetxt("b.txt", b, delimiter=",")
In[192]: b1, b2 = loadtxt("b.txt", delimiter=",", usecols=(3, 4), unpack=True)
In[193]: b1, b2
Out[192]: (array([ 6., 18., 30., 42.]), array([ 8., 20., 32., 44.]))

保存时参数delimiter可选,用来分隔数组各元素,读取时也要相应地指定这个值,读取时也可只读取部分数据,usecols即用来指定选取的列,unpack设置为True时表示将这些列分开存储。

读写时遇到字符串(如时间)可以通过指定参数converters来转换。

In[252]: 
def datestr2num(s):
  return datetime.datetime.strptime(str(s, encoding="utf-8"), "%Y-%m-%d").date().weekday()
weeks, numbers = loadtxt("b.txt", converters={0:datestr2num}, unpack=True)
In[253]: weeks
Out[252]: array([ 2., 4.])

2.3 通用函数

frompyfunc函数可以将一个作用在单一数值的函数映射到作用在数组上的函数:

In[49]: def f(i):
...   return 2*i
...   
In[50]: ff = frompyfunc(f, 1, 1)
In[52]: ff(a)
Out[52]: 
array([[0, 2, 4, 6, 8, 10],
    [12, 14, 16, 18, 20, 22],
    [24, 26, 28, 30, 32, 34],
    [36, 38, 40, 42, 44, 46]], dtype=object)

frompyfunc的两个参数分别定义输入参数和输出参数的个数

另外,numpy提供了一些常用的通用函数,如针对加减乘除的add、subtract、multiply和divide。通用函数都有四个方法:reduce、accumulate、reduceat和outer,以add函数为例:

In[64]: add.reduce(a[0, :])
Out[64]: 15
In[65]: add.accumulate(a[0,:])
Out[65]: array([ 0, 1, 3, 6, 10, 15], dtype=int32)
In[69]: add.reduceat(a[0, :], [0, 5, 2, 4])
Out[69]: array([10, 5, 5, 9], dtype=int32)
In[70]: add.outer(a[0, :], a[1, :])
Out[70]: 
array([[ 6, 7, 8, 9, 10, 11],
    [ 7, 8, 9, 10, 11, 12],
    [ 8, 9, 10, 11, 12, 13],
    [ 9, 10, 11, 12, 13, 14],
    [10, 11, 12, 13, 14, 15],
    [11, 12, 13, 14, 15, 16]])

可见,reduce是将通用函数递归作用在所有元素上,得到最后结果;accumulate也是递归作用在所有元素上,不过它保留中间结果并返回;reduceat则根据指定的起始点进行累积运算,如果终点小于起点,则返回终点处的值;最后outer则是对两个输入数组的所有元素组合进行运算。

3 科学计算

3.1 统计分析

3.1.1 基本统计分析

average函数可以非常方便地计算加权平均值,或者用mean计算算术平均值:

In[204]: a = array([1, 2])
In[205]: average(a, weights=[1,2])
Out[204]: 1.6666666666666667

基本统计分析函数整理如下:

中位数median
方差var
标准差std
差分diff
最值maxminargmaxargmin(后两个得到最值所在的下标)

3.1.2 随机过程分析

3.2 线性代数

先生成一个各元素是0~1之内的随机数的矩阵:

In[47]: a = mat(fromiter((random.random() for i in range(9)), dtype = float32).reshape(3, 3))
In[48]: a
Out[48]: 
matrix([[ 0.45035544, 0.53587919, 0.57240343],
    [ 0.54386997, 0.16267321, 0.97020519],
    [ 0.6454953 , 0.38505632, 0.94705021]], dtype=float32)

接下我们可以对它进行各种线性代数的操作, 如:

求逆:

In[49]: a.I
Out[49]: 
matrix([[-10.71426678, -14.01229095, 20.83065987],
    [ 5.42686558,  2.7832334 , -6.13131571],
    [ 5.09620285,  8.41894722, -10.64905548]], dtype=float32)

解线性方程组(用点积验证了结果):

In[59]: b = fromiter((random.random() for i in range(3)), dtype = float32)
In[60]: b
Out[60]: array([ 0.56506187, 0.99419129, 0.70462942], dtype=float32)
In[61]: linalg.solve(a, b)
Out[61]: array([-5.3072257 , 1.51327574, 3.74607611], dtype=float32)
In[63]: dot(a, _)
Out[63]: matrix([[ 0.56506193, 0.99419105, 0.70462948]], dtype=float32)

求特征值和特征向量:

In[64]: linalg.eig(a)
Out[64]: 
(array([ 1.78036737, -0.08517434, -0.13511421], dtype=float32),
 matrix([[-0.5075314 , -0.82206506, 0.77804375],
     [-0.56222379, 0.4528676 , -0.57155234],
     [-0.65292901, 0.34513769, -0.26072171]], dtype=float32))

行列式:

In[81]: linalg.det(a)
Out[81]: 0.020488938

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
举例讲解Python中的身份运算符的使用方法
Oct 13 Python
python的Crypto模块实现AES加密实例代码
Jan 22 Python
Python cookbook(数据结构与算法)从任意长度的可迭代对象中分解元素操作示例
Feb 13 Python
python 借助numpy保存数据为csv格式的实现方法
Jul 04 Python
Python图像处理之图像的读取、显示与保存操作【测试可用】
Jan 04 Python
Python学习笔记之变量、自定义函数用法示例
May 28 Python
浅谈python多进程共享变量Value的使用tips
Jul 16 Python
python3实现单目标粒子群算法
Nov 14 Python
python剪切视频与合并视频的实现
Mar 03 Python
python GUI库图形界面开发之PyQt5动态(可拖动控件大小)布局控件QSplitter详细使用方法与实例
Mar 06 Python
django下创建多个app并设置urls方法
Aug 02 Python
Python NumPy灰度图像的压缩原理讲解
Aug 04 Python
Python多进程并发与多线程并发编程实例总结
Feb 08 #Python
Python的CGIHTTPServer交互实现详解
Feb 08 #Python
Python获取CPU、内存使用率以及网络使用状态代码
Feb 08 #Python
python实现二叉查找树实例代码
Feb 08 #Python
单链表反转python实现代码示例
Feb 08 #Python
Python测试人员需要掌握的知识
Feb 08 #Python
python实现单向链表详解
Feb 08 #Python
You might like
php获取textarea的值并处理回车换行的方法
2014/10/20 PHP
php+mysqli实现批量替换数据库表前缀的方法
2014/12/29 PHP
PHP通过API获取手机号码归属地
2015/05/28 PHP
discuz图片顺序混乱解决方案
2015/07/29 PHP
Yii使用Captcha验证码的方法
2015/12/28 PHP
YII使用url组件美化管理的方法
2015/12/28 PHP
讨论javascript(一)工厂方式 js面象对象的定义方法
2009/12/15 Javascript
jQuery使用fadeout实现元素渐隐效果的方法
2015/03/27 Javascript
jquery验证手机号是否正确实例讲解
2015/11/17 Javascript
JavaScript tab选项卡插件实例代码
2016/02/23 Javascript
JavaScript动态检验密码强度的实现方法
2016/11/09 Javascript
layer实现弹窗提交信息
2016/12/12 Javascript
详解nodejs express下使用redis管理session
2017/04/24 NodeJs
BootStrap 动态表单效果
2017/06/02 Javascript
浅谈JavaScript 代码简洁之道
2019/01/09 Javascript
Antd-vue Table组件添加Click事件,实现点击某行数据教程
2020/11/17 Javascript
[45:44]完美世界DOTA2联赛PWL S2 FTD vs PXG 第一场 11.27
2020/12/01 DOTA
python中的一些类型转换函数小结
2013/02/10 Python
Eclipse + Python 的安装与配置流程
2013/03/05 Python
python文件读写并使用mysql批量插入示例分享(python操作mysql)
2014/02/17 Python
浅谈使用Python变量时要避免的3个错误
2017/10/30 Python
python使用正则表达式替换匹配成功的组
2017/11/17 Python
numpy 进行数组拼接,分别在行和列上合并的实例
2018/05/08 Python
Python实现网页截图(PyQT5)过程解析
2019/08/12 Python
python学生管理系统的实现
2020/04/05 Python
搭建pypi私有仓库实现过程详解
2020/11/25 Python
CSS3 文字动画效果
2020/11/12 HTML / CSS
GLAMGLOW格莱魅美国官网:美国知名的面膜品牌
2016/12/31 全球购物
下面这个程序执行后会有什么错误或者效果
2014/11/03 面试题
2014年党务公开实施方案
2014/02/27 职场文书
2014年党员教师自我剖析材料
2014/09/30 职场文书
工作失误检讨书(3篇)
2014/10/11 职场文书
房产协议书范本
2014/10/18 职场文书
深入开展党的群众路线教育实践活动心得体会
2014/11/05 职场文书
倡议书怎么写?
2019/04/11 职场文书
解决Vue+SpringBoot+Shiro跨域问题
2021/06/09 Vue.js