创建符合均匀分布的随机数组
numpy.random.rand(d0, d1, …, dn)
d0, d1, …, dn 表征生成数组的维数,若不指定则默认返回一个浮点数。
numpy.random.rand 函数通常用来创建一个服从 “0~1” 均匀分布的随机浮点数(组),随机样本取值范围是[0,1)。
print(np.random.rand())
print(np.random.rand(3,2))
0.2690046670866265
[[0.89634204 0.11035573]
[0.0918894 0.63623696]
[0.3892486 0.86558053]]
numpy.random.uniform(low=0.0, high=1.0, size=None)
low 采样下界,默认值为0;
high 采样上界,默认值为1;采样区间为[low, high)
size 样本维数,为int或tuple类型
numpy.random.uniform 函数可以用来创建一个在指定区间内符合均匀分布的随机数(组)。
在默认情况下,即无任何传参的时候,numpy.random.uniform 和 numpy.random.rand 函数效果类似。
print(np.random.uniform())
0.9275071325568973
print(np.random.uniform(0,10,size=(4,4)))
[[5.36658694 1.00491139 6.60551084 8.08491017]
[6.08066655 2.44990778 6.93738547 7.92597467]
[2.13358618 1.0793497 2.38447094 5.24373378]
[8.86104717 8.66726931 6.9978283 4.78214507]]
numpy.random.randint(low, high=None, size=None, dtype=‘l’)
low 采样下界,整数类型。当high不指定时,采样区间为[0, low)
high 采样上界,可选。采样区间为[low, high)
size 样本维数,为int或tuple类型
dtype 数组数据类型,可选.
numpy.random.randint 函数可以用来创建一个在指定区间内符合均匀分布的随机整数(数组)
print(np.random.randint(10))
print(np.random.randint(0,100,size=10,dtype=np.int16))
3
[ 4 41 64 73 50 42 36 41 25 63]
创建符合正态分布的随机数组
numpy.random.randn(d0, d1, …, dn)
d0, d1, …, dn 表征生成数组的维数,若不指定则默认返回一个浮点数。
numpy.random.randn 函数可以用来创建一个指定维度的、符合标准正态分布(以0为均值、1为标准差)的浮点数(数组)。
print(np.random.randn())
print(np.random.randn(3,2))
-0.16537871841907784
[[ 1.00381782 0.22891542]
[-1.31329439 -0.18088433]
[ 0.09623652 2.92044164]]
numpy.random.normal(loc=0.0, scale=1.0, size=None)
loc 采样样本分布的均值
scale 采样样本分布的标准差
size 样本维数,为int或tuple类型
numpy.random.normal 函数可以用来创建一个指定维度的、符合指定正态分布(以loc为均值、scale为标准差)的浮点数(数组)。
在不指定均值和标准差的时候,numpy.random.normal 会产生一个符合标准正态分布的浮点数:
print(np.random.normal())
print(np.random.normal(5,10,(3,2)))
1.9307238923955998
[[ 7.17923195 20.25280746]
[18.42725503 6.6526095 ]
[12.79639438 14.7733698 ]]
单一元素访问
一维数组的元素访问非常简单,和 Python 列表规则基本差不多。对单一元素的访问,索引遵循从 0 开始,依次递增 1。
arr=np.arange(10)
print(arr)
print(arr[4])
print(arr[-1])
[0 1 2 3 4 5 6 7 8 9]
4
9
切片索引
1.基本切片。
arr=np.arange(10)
print(arr[[0,-1]])
[0 9]
2.利用start、stop、step
的方法访问。
arr=np.arange(10)
print(arr[0:-1:2])
[0 2 4 6 8]
我们来访问奇数:
arr=np.arange(10)
print(arr[1:-1:2])
[1 3 5 7]
arr=np.arange(10)
print(arr[1::2])
[1 3 5 7 9]
对比发现当stop是-1时,最后一位索引序列时无法获取的。
3.多维数组切片索引。
arr = np.arange(16).reshape(4, 4)
print(arr)
print(arr[0][1:3]) # 第0行,第1,2列
print(arr[0:2, 1:3]) # 第0,1行,第1,2列
print(arr[:, 1:3]) # 所有行,第1,2列
[[ 0 1 2 3]#print(arr)
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
[1 2]#print(arr[0][1:3])
[[1 2]#print(arr[0:2, 1:3])
[5 6]]
[[ 1 2]#print(arr[:, 1:3])
[ 5 6]
[ 9 10]
[13 14]]
布尔型索引
arr = np.arange(16).reshape(4, 4)
print(arr)
print(arr[[True, True, False, False]]) # 第一行和第二行
print(arr[:, [True, True, False, False]]) # 第一列和第二列
[[ 0 1 2 3]#print(arr)
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
[[0 1 2 3]#print(arr[[True, True, False, False]])
[4 5 6 7]]
[[ 0 1]#print(arr[:, [True, True, False, False]])
[ 4 5]
[ 8 9]
[12 13]]
数组元素访问
在默认情况下,numpy.nditer 迭代器返回的元素顺序,是和数组内存布局一致的,这样做是为了提升访问的效率,默认是行序优先。
arr = np.arange(6).reshape(2, 3)
print(arr)
for i in np.nditer(arr):
print(i, end=' ')
[[0 1 2]
[3 4 5]]
0 1 2 3 4 5
在不改变内部布局的情况下,通过该方式进行遍历,并不会改变顺序:
arr = np.arange(6).reshape(2, 3)
print(arr.T)
print(arr)
for i in np.nditer(arr.T):
print(i, end=' ')
[[0 3]#print(arr.T)
[1 4]
[2 5]]
[[0 1 2]#print(arr)
[3 4 5]]
0 1 2 3 4 5 #print(i, end=' ')
相对应的,我们利用 copy 方法,显式地更改内存顺序,nditer 迭代器的遍历解雇也会发生响应的变化:
arr = np.arange(6).reshape(2, 3)
for i in np.nditer(arr.T.copy("C")):
print(i, end=' ')
0 3 1 4 2 5
nditer
提供了order
参数来达到同样的目的。
arr = np.arange(6).reshape(2, 3)
for i in np.nditer(arr,order='C'):
print(i, end=' ')
print('\n')
for i in np.nditer(arr,order='F'):
print(i, end=' ')
0 1 2 3 4 5
0 3 1 4 2 5
数组元素修改
nditer 对象有另一个可选参数 op_flags。 默认情况下,nditer 将视待迭代遍历的数组为只读对象(read-only),为了在遍历数组的同时,实现对数组元素值得修改,必须指定 read-write 或者 write-only 的模式。
arr = np.arange(16).reshape(4, 4)
print(arr)
for i in np.nditer(arr, op_flags=["readwrite"]):
i[...] = i ** 2
print(arr)
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
[[ 0 1 4 9]
[ 16 25 36 49]
[ 64 81 100 121]
[144 169 196 225]]
flags 可选参数
flags
参数可以接受传入一个数组或元组,它可以接受下列值:
c_index 可以跟踪 C 顺序的索引
f_index 可以跟踪multi-index 每次迭代可以跟踪多重索引类型
external_loop 给出的值是具有多个值的一维数组,而不是零维数组
flags=["c_index"]
:
arr = np.arange(6).reshape(2, 3)
cit = np.nditer(arr, flags=["c_index"])
while not cit.finished:
print("value:", cit[0], "index:<{}>".format(cit.index))
cit.iternext()
value: 0 index:<0>
value: 1 index:<1>
value: 2 index:<2>
value: 3 index:<3>
value: 4 index:<4>
value: 5 index:<5>
flags=["f_index"]
:
arr = np.arange(6).reshape(2, 3)
fit = np.nditer(arr, flags=["f_index"])
while not fit.finished:
print("value:", fit[0], "index:<{}>".format(fit.index))
fit.iternext()
value: 0 index:<0>
value: 1 index:<2>
value: 2 index:<4>
value: 3 index:<1>
value: 4 index:<3>
value: 5 index:<5>
对于 arr 这样的二维数组,可以用 2 个维度(x 方向和 y 方向)的序列来唯一定位每一个元素,multi-index
则可以打印出该种索引顺序。
arr = np.arange(6).reshape(2, 3)
mul_it = np.nditer(arr, flags=["multi_index"])
while not mul_it.finished:
print("value:",mul_it[0],"index:<{}>".format(mul_it.multi_index))
mul_it.iternext()
value: 0 index:<(0, 0)>
value: 1 index:<(0, 1)>
value: 2 index:<(0, 2)>
value: 3 index:<(1, 0)>
value: 4 index:<(1, 1)>
value: 5 index:<(1, 2)>
将一维的最内层的循环转移到外部循环迭代器,使得 NumPy 的矢量化操作在处理更大规模数据时变得更有效率。简单来说,当指定 flags=['external_loop']
时,将返回一维数组而并非单个元素。
具体来说,当 ndarray 的顺序和遍历的顺序一致时,将所有元素组成一个一维数组返回;当 ndarray 的顺序和遍历的顺序不一致时,返回每次遍历的一维数组。
arr = np.arange(6).reshape(2, 3)
for i in np.nditer(arr, flags=['external_loop'], order='C'):
print(i)
# 对于上述创建的 arr,是行优先顺序的数组。当我们指定遍历顺序为C(行优先,与定义的顺序一致),指定 flags=["external_loop"]时,把所有元素组成一个数组,并返回
for i in np.nditer(arr, flags=['external_loop'], order='F'):
print(i)
# 当我们指定遍历顺序为F(列优先),指定 flags=["external_loop"]时,返回每次遍历的一维数组。
[0 1 2 3 4 5]
[0 3]
[1 4]
[2 5]
常见的两种广播途径
相同大小的数组计算
arr0=np.array([[1,2,3],[4,5,6]])
arr1=np.array([[5,5,5],[5,5,5]])
print(arr0)
print(arr1)
print(arr0+arr1)
print(arr0*arr1)
print(arr0+5)
print(arr0*5)
print(arr0**5)
[[1 2 3]#print(arr0)
[4 5 6]]
[[5 5 5]#print(arr1)
[5 5 5]]
[[ 6 7 8]#print(arr0+arr1)
[ 9 10 11]]
[[ 5 10 15]#print(arr0*arr1)
[20 25 30]]
[[ 6 7 8]#print(arr0+5)
[ 9 10 11]]
[[ 5 10 15]#print(arr0*5)
[20 25 30]]
[[ 1 32 243]#print(arr0**5)
[1024 3125 7776]]
数组的维度一样,广播则对应元素运算。
不同维度的数组的运算
沿一个维度进行广播
arr0=np.array([[1,2,3],[4,5,6]])
arr2=np.array([[10,20,30]])
print(arr0+arr2)
print(arr0*arr2)
[[11 22 33]# =[1,2,3] +[10,20,30]
[14 25 36]]# [4,5,6] [10,20,30]
[[ 10 40 90]# =[1,2,3] * [10,20,30]
[ 40 100 180]]# [4,5,6] [10,20,30]
沿两个维度同时广播
arr2 = np.array([[10, 20, 30]])
arr3 = np.array([[10], [20], [30]])
print(arr3)
print(arr2+arr3)
[[10]#print(arr3)
[20]
[30]]
[[20 30 40]# =[10,20,30] + [10,10,10]
[30 40 50]# [10,20,30] [20,20,20]
[40 50 60]]# [10,20,30] [30,30,30]
小结:
1.生成随机数
均匀分布:
numpy.random.rand()
numpy.random.uniform()
numpy.random.randint()
正态分布:
numpy.random.randn()
numpy.random.normal()
2.索引和切片
单一元素访问:
例arr[4]
切片:
基本切片
多维数组切片索引
布尔型索引
3.遍历数组
按照内存布局打印数组元素:
for i in np.nditer(arr):
print(i,end=' ')
控制遍历顺序:
for i in np.nditer(arr,order=' C or F'):
print(i,end=' ')
数组元素修改:
for i in np.nditer(arr, op_flags=["readwrite"]):
i[...] = i ** 2
flags可选参数:
flags=["c_index"]
flags=["f_index"]
flags=["multi_index"]
flags=['external_loop']
4.数组运算与广播
相同大小数组的计算
数组与标量的计算
沿一个维度广播
沿两个维度广播