多维数组的下标存取
一声霹雳醒蛇虫,几阵潇潇染紫红。
九九江南风送暖,融融翠野启农耕。
首先,多维数组的下标应该是一个长度和数组维数相同的元组,如果下标元组的长度比数组的维数大,就会出错,如果小,就会在下标元组的后面补“:”,使得他的长度与数组的维数相同,如果下标对象不是元组的画,则NumPy会首先把它转化成数组。这种转化可能会和用户所希望的不一致,所以为了避免出现这种问题,还是需要自己“显式”的使用元组作为下标。
from PIL import Image import numpy as np a = np.arange(3*4*5).reshape(3,4,5) lidx = [[0],[1]] # 直接使用列表 aidx = np.array(lidx) # 显式的转化为数组 print(a[lidx]) print("_____________________") print(a[aidx])
[[5 6 7 8 9]] _____________________ [[[[ 0 1 2 3 4] [ 5 6 7 8 9] [10 11 12 13 14] [15 16 17 18 19]]] [[[20 21 22 23 24] [25 26 27 28 29] [30 31 32 33 34] [35 36 37 38 39]]]]
这是因为NumPy将列表lidx转化成了([0],[1]),而讲述组aidx转化成了(aidx,:,:u)
庞大的函数库
numpy.random模块中提供了大量的随机数相关的函数,为了方便后面用随机数测试各种运算函数,让我们首先来看看如何产生随机数。
- rand() 产生0-1之间的随机浮点数,其参数用于指定所产生数组的形状。
- randn() 用于产生标准正态分布的随机数,参数的含义与rand() 相同。
- randint() 用于产生指定范围的随机整数,包括起始值,但是不包括终止值,在下面的例子中,产生0-9的随机数,第三个参数用于指定数组形状。
from numpy import random as nr np.set_printoptions(precision = 2) # 只显示小数点后两位数字。 r1 = nr.rand(4,3) # 指定数组形状产生0-1 之间的随机数 r2 = nr.randn(4,3) # 指定数组形状, r3 = nr.randint(0,10,(4,3)) print(r1) print(r2) print(r3)
[[ 0.09 0.06 0.7 ] [ 0.48 0.83 0.39] [ 0.71 0.46 0.03] [ 0.61 0.82 0.99]] [[-0.36 0.48 0.59] [-0.88 0.26 1.87] [ 2.03 -1.88 -0.15] [ 1.18 2.07 0.76]] [[3 8 0] [2 6 9] [5 7 6] [9 0 7]]
random模块 提供了许多产生符合特定随机分布的随机数的函数,它们的最后一个参数size都用与指定输出数组的形状,而其他参数都是分布函数的参数。例如:
- normal():正态分布,前两个参数分别是期望值和标准差。
- uniform():均匀分布,前两个参数分别是区间的起始值和终止值。
- poisson():泊松分布,第一个参数指定入系数,他表示单位时间(或单位面积)内随机时间的平均发生率。由于泊松分布是一个离散分布,因此输出的数组是一个整数数组。
r1 = nr.normal(100,10,(4,3)) # 期望值100 标准差10 矩阵形状4,3 r2 = nr.uniform(10,20,(4,3)) # 平均分补:起始值,终止值,矩阵形状 r3 = nr.poisson(2.0,(4,3)) # 泊松分布:入值 , 矩阵形状 print(r1) print(r2) print(r3)
[[ 97.28 93.81 87.9 ] [ 106.75 86.09 93.2 ] [ 115.84 111.88 99.29] [ 102.32 86.94 90.57]] [[ 10.89 13.09 13.72] [ 19.79 15.47 18.8 ] [ 14.69 19.04 12.07] [ 19.54 19.97 13.17]] [[5 1 1] [3 2 2] [4 0 2] [0 2 2]]
关于泊松分布,如果这一家商店今天赚了两块钱,然后分析明天转0圆的概率是多少。
>>> a = nr.poisson(2,1000000) >>> a array([1, 3, 2, ..., 4, 3, 2]) >>> count = 0 >>> for i in a: ... if i ==0 : ... count += 1 ... ... ... >>> count 135636 >>> count/1000000 0.135636
permutation() 可以用于产生一个乱序数组,当参数为整数n 时他返回 [0,n)这n个正整数的随机排列,当参数为一个序列的时候他返回一个随机排列的序列。
>>> nr.permutation(10) array([8, 6, 7, 0, 4, 9, 1, 3, 5, 2]) >>> nr.permutation([1,2,3,4,5,6,67]) array([ 6, 3, 5, 4, 67, 2, 1])
permutation() 是返回一个新数组,而shuffle() 则是将原有的数组序列打乱。
>>> a array([ 1, 2, 3, 45, 56, 6, 78]) >>> nr.shuffle(a) >>> a array([45, 6, 56, 3, 78, 1, 2])
choice() 从指定的样本中抽取数据:
- size参数用于指定输出数组的形状
- replace 参数位True时,进行可重复抽取,默认值为True
- p 参数指定每个元素的对应抽取概率,如果不指定的话,所有元素的概率相同,在下面的例子中值越大的被抽取到的概率也就越大。
a = np.arange(10,25,dtype = float) c1 = nr.choice(a,size = (4,3)) # 从a 中随机可重复选取元素组成一个 4,3 的矩阵 c2 = nr.choice(a,size = (4,3),replace = False) c3 = nr.choice(a,size = (4,3),p = a/np.sum(a)) print(c1) print() print(c2) print() print(c3)
[[ 24. 16. 17.] [ 18. 22. 21.] [ 20. 21. 10.] [ 11. 20. 18.]] [[ 15. 24. 21.] [ 11. 12. 17.] [ 14. 22. 16.] [ 18. 10. 13.]] [[ 20. 21. 13.] [ 24. 14. 13.] [ 21. 17. 19.] [ 24. 21. 19.]]
庞大的函数库
除了前面介绍的ndarray数组对象和ufunc函数之外,Numpy还提供了大量的对数组进行处理的函数,充分利用这些函数,能够简化程序的逻辑,提高运算速度。