python科学计算库教程_Python最好用的科学计算库:NumPy快速入门教程(一)

首先导入并检查你的numpy版本

import numpy

numpy.__version__

'1.14.3'

NumPy数组

NumPy数组指的是由同一类型元素(一般是数字)组成的多维数组。

基础知识

数组的维度、形状、大小

一维数组由一个中括号内的数字组成。

import numpy as np #这里的一个惯例是使用np作为numpy的别名

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

>>>a

array([1, 2, 3])

二维数组由多个一维数组组成

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

>>>b

array([[1, 2, 3],

[4, 5, 6],

[7, 8, 9]])

同理,n维数组由多个n-1维数组组成

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

>>>c

array([[[1, 2, 1],

[1, 3, 2]],

[[2, 2, 2],

[1, 1, 1]]])

查看数组的维度使用np.ndim

>>>print('数组a的维度是:',a.ndim)

>>>print('数组b的维度是:',b.ndim)

>>>print('数组c的维度是:',c.ndim)

数组a的维度是: 1

数组b的维度是: 2

数组c的维度是: 3

np.shape:显示在每个维度里数组的大小,或者说数组的“形状”。如 n 行 m 列的矩阵,它的 shape 就是(n,m)。

>>>print('数组a的形状是:',a.shape)

>>>print('数组b的形状是:',b.shape)

>>>print('数组c的形状是:',c.shape)

数组a的形状是: (3,)

数组b的形状是: (3, 3)

数组c的形状是: (2, 2, 3)

np.size:数组中所有元素的总量,相当于数组的 shape 中所有元素的乘积,例如矩阵的元素总量为行与列的乘积。

>>>print('数组a的大小是:',a.size)

>>>print('数组b的大小是:',b.size)

>>>print('数组c的大小是:',c.size)

数组a的大小是: 3

数组b的大小是: 9

数组c的大小是: 12

数组的元素类型和存储大小

np.dtype:查看数组中元素的类型。创建数组时,可以指定dtype参数用于创建指定数据类型的数组

>>>a.dtype

dtype('int64')

>>>d = np.array([1.2, 2.3, 3.4], dtype = np.float)

>>>d

array([1.2, 2.3, 3.4])

np.itemsize:用于查看数组中元素占用的字节,例如,一个元素类型是float64的数组,其中的元素占用的字节大小是8(也就是64bit/8)

>>>d.itemsize

8

np.data:查看存储数组的真实内存地址

>>>d.data

创建数组

有很多种方法创建数组。

例如,你可以通过使用数组函数从一个python的列表或元组创建。数组元素的类型由原数据的类型推断得到。

>>>b = np.array([1.2, 3.5, 5.1])

>>>b.dtype

dtype('float64')

np.array创建数组时,会将多层嵌套的列表转换为多维数组。

>>>b = np.array([(1.5,2,3), (4,5,6)])

>>>b

array([[1.5, 2. , 3. ],

[4. , 5. , 6. ]])

创建数组时我们还可以指定数据类型

>>>c = np.array( [ [1,2], [3,4] ], dtype=complex )#指定数据类型为复数

>>>c

array([[1.+0.j, 2.+0.j],

[3.+0.j, 4.+0.j]])

我们经常遇到这样的情况,我们并不知道数组的元素,但是知道数组的大小。因此,NumPy提供了多个函数,用于创建有初始数值的占位数组,这样可以减少不必要的数组增长及运算成本。

zeros函数创建包含全是0的数组,ones函数创建全是1的数组,empty函数创建一个随机数值数组,其中的数值由当时的内存状态决定。这些函数创建的数组的数据类型都是默认的float64.

>>>np.zeros( (3,4) )

array([[0., 0., 0., 0.],

[0., 0., 0., 0.],

[0., 0., 0., 0.]])

>>>np.ones( (2,3,4), dtype=np.int16 )

array([[[1, 1, 1, 1],

[1, 1, 1, 1],

[1, 1, 1, 1]],

[[1, 1, 1, 1],

[1, 1, 1, 1],

[1, 1, 1, 1]]], dtype=int16)

>>>np.empty( (2,3) )

array([[1.5, 2. , 3. ],

[4. , 5. , 6. ]])

为了生成连续的数值,NumPy提供了一个模拟range的函数,不同点是,numpy的range返回的是数组而不是列表

>>>np.arange( 10, 30, 5 ) # 三个参数分别代表起始值10,终止值30,步进5

array([10, 15, 20, 25])

>>>np.arange( 0, 2, 0.3 )

array([0. , 0.3, 0.6, 0.9, 1.2, 1.5, 1.8])

当 arange 使用浮点型作为参数时,因为浮点精度的有限性,不能预测创建的数组有多少个元素。在这种情况下,换成linspace函数可以更好地确定区间内到底需要产生多少个数组元素。

from numpy import pi

>>>np.linspace( 0, 2, 9 ) # 在[0,2]区间内生成9个值

array([0. , 0.25, 0.5 , 0.75, 1. , 1.25, 1.5 , 1.75, 2. ])

打印数组

当你在屏幕打印一个数组时,NumPy显示这个数组的方式和嵌套的列表是相似的。但遵守以下布局:最后一维由左至右打印

倒数第二维从上到下打印

其余维都是从上到下打印,且通过空行分隔

如下所示,一维数组输出为一行、二维为矩阵、三维为矩阵列表。

>>>a = np.arange(6)

>>>a

array([0, 1, 2, 3, 4, 5])

>>>b = np.arange(12).reshape(4,3)

>>>a

array([0, 1, 2, 3, 4, 5])

>>>c = np.arange(24).reshape(2,3,4)

>>>c

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]]])

如果数组太大了,NumPy自动跳过中间的部分不显示,只显示两边。

>>>print(np.arange(10000))

[ 0 1 2 ... 9997 9998 9999]

>>>print(np.arange(10000).reshape(100,100))

[[ 0 1 2 ... 97 98 99]

[ 100 101 102 ... 197 198 199]

[ 200 201 202 ... 297 298 299]

...

[9700 9701 9702 ... 9797 9798 9799]

[9800 9801 9802 ... 9897 9898 9899]

[9900 9901 9902 ... 9997 9998 9999]]

如果你想强制输出所有数据,可以设置set_printoptions参数。

>>>np.set_printoptions(threshold=np.nan)

基本运算

数组中的算术运算一般是元素级的运算,运算结果会产生一个新的数组。

不同于很多矩阵语言,乘积运算操作*在NumPy中是元素级的运算。如果想要进行矩阵运算,可以使用dot函数或方法。

>>>A = np.array( [[1,1],[0,1]] )

>>>B = np.array( [[2,0],[3,4]] )

>>>A*B# 元素乘积

array([[2, 0],

[0, 4]])

>>>A.dot(B)# 矩阵运算

array([[5, 4],

[3, 4]])

>>>np.dot(A, B)# 另一种方式矩阵运算

array([[5, 4],

[3, 4]])

一些运算,例如+=和*=,会内在的改变一个数组的值,而不是生成一个新的数组。

>>>a = np.ones((2,3), dtype=int)

>>>b = np.random.random((2,3))

>>>a *= 3

>>>a

array([[3, 3, 3],

[3, 3, 3]])

>>>b += a

>>>b

array([[3.69902298, 3.1334804 , 3.62673199],

[3.37038178, 3.74769131, 3.62235315]])

>>>a += b # b不会自动转换为整型

---------------------------------------------------------------------------

TypeError Traceback (most recent call last)

in ()

----> 1 a += b # b不会自动转换为整型

TypeError: Cannot cast ufunc add output from dtype('float64') to dtype('int64') with casting rule 'same_kind'

当操作不同数据类型的数组时,最后输出的数组类型一般会与更普遍或更精准的数组相同(这种行为叫做 Upcasting)。

>>>a = np.ones(3, dtype=np.int32)

>>>b = np.linspace(0,pi,3)

>>>b.dtype.name

'float64'

>>>c = a+b

>>>c.dtype.name

'float64'

>>>d = np.exp(c*1j)

>>>d.dtype.name

'complex128'

许多一元运算,如计算数组中所有元素的总和,是属于 ndarray 类的方法。

>>>a = np.random.random((2,3))

>>>a

array([[0.85827711, 0.5385761 , 0.0843277 ],

[0.2609027 , 0.36414539, 0.12940627]])

>>>a.sum()

2.2356352707158513

>>>a.min()

0.08432769616897462

>>>a.max()

0.8582771053112916

默认状态下,这些运算会把数组视为一个数字列表而不关心它的shape。然而,可以指定axis参数针对哪一个维度进行运算。例如axis=0将针对每一个列进行运算。

>>>b = np.arange(12).reshape(3,4)

>>>b

array([[ 0, 1, 2, 3],

[ 4, 5, 6, 7],

[ 8, 9, 10, 11]])

>>>b.sum(axis=0)# 列相加

array([12, 15, 18, 21])

>>>b.min(axis=1) #行相加

array([0, 4, 8])

>>>b.cumsum(axis=1)#行累加

array([[ 0, 1, 3, 6],

[ 4, 9, 15, 22],

[ 8, 17, 27, 38]])

通用函数

NumPy提供一些熟悉的数学函数,例如sin, cos,和exp等。在NumPy中,这些函数称为“通用函数”, 这些运算是元素级的,生成一个数组作为结果。

>>>B = np.arange(3)

>>>B

array([0, 1, 2])

>>>np.exp(B)

array([1. , 2.71828183, 7.3890561 ])

>>>np.sqrt(B)

array([0. , 1. , 1.41421356])

>>>C = np.array([2., -1., 4.])

>>>np.add(B, C)

array([2., 0., 6.])

索引、切片和迭代

一维数组可以索引、切片和迭代,就像列表和其他python数据类型。

>>>a = np.arange(10)**3

>>>a[2]

8

>>>a[2:5]

array([ 8, 27, 64])

>>>a[:6:2] = -1000 #从0到6,每隔2个设为-1000

>>>a

array([-1000, 1, -1000, 27, -1000, 125, 216, 343, 512,

729])

>>>a[ : :-1] #翻转数组a

array([ 729, 512, 343, 216, 125, -1000, 27, -1000, 1,

-1000])

多维数组可以每个维度有一个索引值。这些索引值被逗号分开。

>>>def f(x,y):#定义一个函数用于生成数组

>>> return 10*x+y

>>>b = np.fromfunction(f,(5,4),dtype=int)#利用函数f生成数组,数组的形状是(5,4),数组中(x,y)的元素值等于 f(x,y)

>>>b

array([[ 0, 1, 2, 3],

[10, 11, 12, 13],

[20, 21, 22, 23],

[30, 31, 32, 33],

[40, 41, 42, 43]])

>>>b[2,3] #第2行,第3列

23

>>>b[0:5, 1] #等于b[ : ,1] ,第0-5行,第1列

array([ 1, 11, 21, 31, 41])

>>>b[1:3, : ] #1-3行,所有列

array([[10, 11, 12, 13],

[20, 21, 22, 23]])

当索引值的数量少于数组的维度时,其他的索引值默认为分号:

>>>b[-1] #相当于b[-1,:]

array([40, 41, 42, 43])

b[i]中的i代表i后面有足够多的:,用于表示其他维度的索引。你也可以使用点号...来表示。

点号代表需要的足够多的列,用于使其他维度的索引值完整。例如,x是一个五维数组,那么x[1,2,...] 相当于 x[1,2,:,:,:]

x[...,3] 相当于 x[:,:,:,:,3]

x[4,...,5,:] 相当于 x[4,:,:,5,:]

>>>c = np.array( [[[ 0, 1, 2], #构建一个三维数组

[ 10, 12, 13]],

[[100,101,102],

[110,112,113]]])

>>>c.shape

(2, 2, 3)

>>>c[1,...]

array([[100, 101, 102],

[110, 112, 113]])

>>>c[...,2]

array([[ 2, 13],

[102, 113]])

多维数组中的迭代:

>>>for row in b:

>>> print(row)

[0 1 2 3]

[10 11 12 13]

[20 21 22 23]

[30 31 32 33]

[40 41 42 43]

但是,如果你想迭代输出数组中的每一个元素,你可以使用flat属性实现,这个属性生成一个可以迭代所有元素的迭代器。

>>>for element in b.flat:

>>> print(element)

0

1

2

3

10

11

12

13

20

21

22

23

30

31

32

33

40

41

42

43

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值