python:Numpy(2)

本文详细介绍了Numpy库中创建均匀分布和正态分布随机数的方法,包括numpy.random.rand、numpy.random.uniform、numpy.random.randint以及numpy.random.randn和numpy.random.normal。此外,还探讨了Numpy数组的索引、切片、布尔型索引和元素访问及修改,以及flags参数的作用。最后,阐述了Numpy数组运算中的广播机制,包括相同大小数组、不同维度数组的运算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • Numpy随机数

创建符合均匀分布的随机数组

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 ]]
  • Numpy的索引和切片

单一元素访问

一维数组的元素访问非常简单,和 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 遍历数组

数组元素访问

在默认情况下,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]
  • Numpy的数组运算和广播

常见的两种广播途径

相同大小的数组计算

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.数组运算与广播
相同大小数组的计算
数组与标量的计算
沿一个维度广播
沿两个维度广播

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值