一声霹雳醒蛇虫,几阵潇潇染紫红。
九九江南风送暖,融融翠野启农耕。
首先,多维数组的下标应该是一个长度和数组维数相同的元组,如果下标元组的长度比数组的维数大,就会出错,如果小,就会在下标元组的后面补“:”,使得他的长度与数组的维数相同,如果下标对象不是元组的画,则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还提供了大量的对数组进行处理的函数,充分利用这些函数,能够简化程序的逻辑,提高运算速度。