当前位置: 首页 > news >正文

Python 之 NumPy 切片索引和广播机制

文章目录

  • 一、切片和索引
    • 1. 一维数组
    • 2. 二维数组
  • 二、索引的高级操作
    • 1. 整数数组索引
    • 2. 布尔数组索引
  • 三、广播机制
    • 1. 广播机制规则
    • 2. 对于广播规则另一种简单理解

一、切片和索引

  • ndarray 对象的内容可以通过索引或切片来访问和修改(),与 Python 中 list 的切片操作一样。
  • ndarray 数组可以基于 0 - n 的下标进行索引(先行后列,都是从 0 开始)。

在这里插入图片描述

  • 区别在于:数组切片是原始数组视图(这就意味着,如果做任何修改,原始都会跟着更改)。 这也意味着,如果不想更改原始数组,我们需要进行显式的复制,从而得到它的副本(.copy())。
  • 冒号分隔切片参数 [start:stop:step]
  • 在开始之前,先导入numpy包
import numpy as np

1. 一维数组

  • 通过 numpy.arange() 生成一个等区间的数组(起始值默认为 0,步长默认为 1,终止值设置为 10)。
ar1 = np.arange(10)
ar1
#array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
  • 从索引 2 开始到索引 7 停止,间隔为 2。
ar2 = ar1[2:7:2]
ar2
#array([2, 4, 6])
  • 这里需要解释以下冒号的作用:
  • 如果只放置一个参数,如果是 [2],将返回与该索引相对应的单个元素;如果为 [2:],表示从该索引开始以后的所有项都将被提取;如果为 [:2],表示不限制开始元素,但会在该元素截止。
  • 如果使用了两个参数,如 [2:7],那么则提取两个索引(不包括停止索引)之间的项。
  • 返回索引对应的数据(注意是从0开始的)。
print('ar1:',ar1)
print('ar1[4]:',ar1[4])
#ar1: [0 1 2 3 4 5 6 7 8 9]
#ar1[4]: 4
  • 通过 numpy.arange() 生成一个等区间的数组(起始值设置为 1,终止值设置为 20,步长设置为 2)。
ar3 = np.arange(1,20,2)
ar3
#array([ 1,  3,  5,  7,  9, 11, 13, 15, 17, 19])
  • 那么,我们如何取出元素 9?
  • 由于索引是从 0 开始的,因此,我们输出 ar3[4] 即可。
  • (1) 从该索引开始以后的所有项都将被提取
  • 从索引 2 开始,提取出后面所有数据。
print(ar3)
ar3[2:]
#[ 1  3  5  7  9 11 13 15 17 19]
#array([ 5,  7,  9, 11, 13, 15, 17, 19])
  • (2) 从索引开始,到索引结束(不包含结束)
  • 从索引 2 开始到索引 7(包含索引 7)。
print(ar3)
ar3[2:7]
ar3[:-2]
#[ 1  3  5  7  9 11 13 15 17 19]
#array([ 1,  3,  5,  7,  9, 11, 13, 15])
  • (3) 步长
  • 取所有数据,步长为 -1(负数代表从右往左数)。
ar3[::-1]
#array([19, 17, 15, 13, 11,  9,  7,  5,  3,  1])
  • 取数据 1 到 17 之间, 并且间隔一位的数据。
ar3[1:-2:2]
print(ar3)
print(ar3[:6])
print(ar3[6:])
#[ 1  3  5  7  9 11 13 15 17 19]
#[ 1  3  5  7  9 11]
#[13 15 17 19]
  • (4) 为什么切片和区间会忽略最后一个元素
  • 计算机科学家 edsger w.dijkstra(艾兹格·W·迪科斯彻),delattr 这一风格的解释应该是比较好的:
  • (1) 当只有最后一个位置信息时,我们可以快速看出切片和区间里有几个元素:range(3) 和 my_list[:3]。
  • (2) 当起始位置信息都可见时,我们可以快速计算出切片和区间的长度,用有一个数减去第一个下表(stop-start)即可。
  • (3) 这样做也让我们可以利用任意一个下标把序列分割成不重叠的两部分,只要写成 my_list[:x] 和 my_list[x:] 就可以了。

2. 二维数组

  • 同样适用上述索引提取方法:
  • 我们定义 4 行 5 列的数据。
  • np.arange(20) 表示起始值默认为 0,终止值设置为 20,步长默认为 1。
  • reshape(4,5) 表示生成一个 4 行 5 列的二维数组。
ar4_5 = np.arange(20).reshape(4,5)
ar4_5
#array([[ 0,  1,  2,  3,  4],
#       [ 5,  6,  7,  8,  9],
#       [10, 11, 12, 13, 14],
#       [15, 16, 17, 18, 19]])
  • 我们通过 ar4_5.ndim 返回 ar4_5 的秩(也就是几维)。
ar4_5.ndim
#2
  • 切片表示的是下一维度的一个元素,所以其代表一维数组。
ar4_5[2]
#array([10, 11, 12, 13, 14])
  • 我们也可以通过二次索引取得一维数组当中的元素。
ar4_5[2][2]
#12
  • 打印出 ar4_5 整体数组,便于后续的操作观察。
print(ar4_5)
#[[ 0  1  2  3  4]
# [ 5  6  7  8  9]
# [10 11 12 13 14]
# [15 16 17 18 19]]
  • 我们可以取出从第三行和第四行的元素。
ar4_5[2:]
#array([[10, 11, 12, 13, 14],
#       [15, 16, 17, 18, 19]])
  • 注意:切片还可以使用省略号 “…”,如果在行位置使用省略号,那么返回值将包含所有行元素,反之,则包含所有列元素。
  • 例如,我们需要取得第二列数据(由于索引是从 0 开始的,因此 第二列的元素就是 1)。
  • 取出的就是每一行和第二列交叉的数据,也就是 1,6,11,16。
ar4_5[...,1]#array([ 1,  6, 11, 16])
  • 我们需要返回第二列后的所有项。
ar4_5[...,1:]
#array([[ 1,  2,  3,  4],
#       [ 6,  7,  8,  9],
#       [11, 12, 13, 14],
#       [16, 17, 18, 19]])
  • 我们需要返回第 2 行第 3 列的数据(对于取出单个数值,两种方法是一样的)。
ar4_5[1,2]  # 对应(1,2) 的元素
#7
  • 对于返回第 2 行第 3 列的数据,我们也可以使用如下方法。
ar4_5[1][2]
#7
  • 对于上述关于取出单个数据的方法,是否可以映射到取出一列元素呢?
  • 如下例子所示,答案是否定的。
  • 首先,我们执行第一步操作,就是 ar4_5[…]。此时,代表取出 ar4_5 的每一行元素,也就是打印 ar4_5 本身。
  • 然后,我们执行第二步操作 ar4_5[…][1] ,就是切片,在 ar4_5 本身上打印处第二行,也就是 [5, 6, 7, 8, 9]。
ar4_5[...][1] 
array([5, 6, 7, 8, 9])

二、索引的高级操作

  • 在 NumPy 中还可以使用高级索引方式,比如整数数组索引、布尔索引,以下将对两种种索引方式做详细介绍。

1. 整数数组索引

  • 我们先创建一个二维数组。
x = np.array([[1,2],[3,4],[5,6]])
y = x[[0,1,2],[0,1,0]] 
y
#array([1,4,5])
  • 其中,[0,1,2] 代表行索引,[0,1,0] 代表列索引,表示 y 分别获取 x 中的 (0,0)、(1,1) 和 (2,0) 表示的数据。
  • 然后,我们先创建一个 43 的数组,创建完成之后,获取了 43 数组中的四个角上元素,它们对应的行索引是 [0,0] 和 [3,3],列索引是 [0,2] 和 [0,2]。
b = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9,10,11]])​
a = b[[0,0,3,3],[0,2,0,2]]  # (0,0) (0,2) (3,0) (3,2)​r = np.array([[0,0] ,[3,3]]).reshape(4) #用r代替[0,0,3,3]
l = np.array([[0,2] ,[0,2]]).reshape(4) #用l代替[0,2,0,2]
s = b[r,l].reshape((2,2))
s
#array([[ 0,  2],
#       [ 9, 11]])
  • 然后,我们先创建一个 3*3 的数组,创建完成之后,行取出第 2 行和第 3 行的元素,列取出第 2 列和第 3 列的数据。
  • 这里需要注意的是,不包含终止索引值。
a = np.array([[1,2,3], [4,5,6],[7,8,9]])
b = a[1:3, 1:3]
b
​#array([[5, 6],
#       [8, 9]])
  • 也就是 1:3 == [1,2]
  • 高级索引操作与常规的索引操作相同,都可以使用 … 表示所有行,1: 表示从第二列开始的所有列。
c = a[1:3,[1,2]]
d = a[...,1:]print(b)
print(c)
print(d)
#[[5 6]
# [8 9]]
#[[5 6]
# [8 9]]
#[[2 3]
# [5 6]
# [8 9]]
  • 在了解了上述高级索引操作之后,我们可以尝试创建一个 8x8 的国际象棋棋盘矩阵,其中黑块代表是 0,白块代表是 1,具体棋盘如下所示。
  1. [0 1 0 1 0 1 0 1]
  2. [1 0 1 0 1 0 1 0]
  3. [0 1 0 1 0 1 0 1]
  4. [1 0 1 0 1 0 1 0]
  5. [0 1 0 1 0 1 0 1]
  6. [1 0 1 0 1 0 1 0]
  7. [0 1 0 1 0 1 0 1]
  8. [1 0 1 0 1 0 1 0]]
  • 对于上述棋盘,我们可以先生成一个 8x8 的全 0 数组,然后将对应的元素设置为 1 即可。
  • (1) 通过行索引从 1 开始,步长为 2,不设置终止值,将第 1,3,5,7 行元素全部设置为 1。
  • (2) 通过列索引从 0 开始,步长为 2,不设置终止值,将第 1,3,5,7 行元素对应的列元素设置为 0。
  • (3) 通过列索引从 1 开始,步长为 2,不设置终止值,将第 1,3,5,7 列元素全部设置为 1。
  • (4) 通过行索引从 0 开始,步长为 2,不设置终止值,将第 1,3,5,7 行元素对应的行元素设置为 0。
  • 具体实现代码如下所示。
Z = np.zeros((8, 8), dtype=int)
Z[1::2,::2] = 1
Z[::2,1::2] = 1
​Z
#array([[0, 0, 0, 0, 0, 0, 0, 0],
#       [1, 0, 1, 0, 1, 0, 1, 0],
#       [0, 0, 0, 0, 0, 0, 0, 0],
#       [1, 0, 1, 0, 1, 0, 1, 0],
#       [0, 0, 0, 0, 0, 0, 0, 0],
#       [1, 0, 1, 0, 1, 0, 1, 0],
#       [0, 0, 0, 0, 0, 0, 0, 0],
#       [1, 0, 1, 0, 1, 0, 1, 0]])

2. 布尔数组索引

  • 当输出的结果需要经过布尔运算(如比较运算)时,此时会使用到另一种高级索引方式,即布尔数组索引。
  • 下面示例返回数组中大于 6 的的所有元素:
x = np.array([[ 0,  1,  2],[ 3,  4,  5],[ 6,  7,  8],[ 9, 10, 11]])
print(x.shape)
x[x>6]
#(4, 3)
#array([ 7,  8,  9, 10, 11])
  • 布尔索引所实现的是通过一维数组中的每个元素的布尔型数值对一个与一维数组有着同样行数或列数的矩阵进行符合匹配。
  • 这种作用,其实是把一维数组中布尔值为 True 的相应行或列给抽取了出来。
  • 这里需要注意的是,一维数组的长度必须和想要切片的维度或轴的长度一致。
  • 练习
  • (1) 提取出数组中所有奇数。
x = np.array([[ 0,  1,  2],[ 3,  4,  5],[ 6,  7,  8],[ 9, 10, 11]])
x[x%2 == 1]
#array([ 1,  3,  5,  7,  9, 11])
  • (2) 将奇数值修改为 -1。
x = np.array([[ 0,  1,  2],[ 3,  4,  5],[ 6,  7,  8],[ 9, 10, 11]])
x[x%2 == 1] = -1
x
#array([[ 0, -1,  2],
#       [-1,  4, -1],
#       [ 6, -1,  8],
#       [-1, 10, -1]])
  • 筛选出指定区间内数据
  • & 表示和。
  • | 表示或。
  • 将数组 x 中大于 4 并且小于 9 的数据提取出来。
x = np.array([[ 0,  1,  2],[ 3,  4,  5],[ 6,  7,  8],[ 9, 10, 11]])
x[(x>4) & (x<9)]
#array([5, 6, 7, 8])
  • 将数组 x 中小于4或者大于 9 的数据提取出来。
x = np.array([[ 0,  1,  2],[ 3,  4,  5],[ 6,  7,  8],[ 9, 10, 11]])
x[(x<4) | (x>9)]#array([ 0,  1,  2,  3, 10, 11])
  • True 和 False 的形式表示需要和不需要的数据
  • 我们先创建 3*4 的数组,元素通过 np.arange(12) 自动生成,表示从起始值 0 到终止值(不包括终止值)12,步长是 1。
a3_4 = np.arange(12).reshape((3,4))
a3_4
#array([[ 0,  1,  2,  3],
#       [ 4,  5,  6,  7],
#       [ 8,  9, 10, 11]])
  • 将行变量和列变量分别用 True 和 False 表示,其中行变量和列变量按如下代码设置。
row1 = np.array([False,True,True])
column1 = np.array([True,False,True,False])
  • a3_4 是 3 行, 做切片时也提供 3 个元素的数组,轴的长度一致。
  • 通过 row1 和 column1 中的 True 和 False 就可以输出我们需要的元素,True 表示需要,False 表示不需要。
a3_4[row1]
#array([[ 4,  5,  6,  7],
#       [ 8,  9, 10, 11]])a3_4[:,column1]
#array([[ 0,  2],
#       [ 4,  6],
#       [ 8, 10]])
  • 那么我们是否可以用两个一维布尔数组进行切片呢?我们继续进行试验得到如下结果:
a3_4[row1,column1]
#array([ 4, 10])
  • 从结果上看,它实际上等价于下面的代码。
a3_4[[1, 2],[0, 2]]
  • 输出的相当于是坐标序号为 (0,1),(2,2) 的数。
  • 索引形状不匹配
  • 从上面的结果可以知道,能够进行切片的前提是:两个一维布尔数组中 True 的个数需要相等,否则会出现下面的情况。
  • 行变量当中存在 2 个 True 元素,列变量当中存在 3 个 True 元素。
row2 = np.array([False,True,True])
​column2 = np.array([True,False,True,True])
  • 其中,行变量和列变量当中的 True 元素个数不一致,会导致错误。
  • a3_4[row2, column2] 就相当于 a3_4[[1,2],[0,2,3]]。
  • 报错信息如下:indexError: shape mismatch: indexing arrays could not be broadcast together with shapes (2,) (3,)。
  • 是因为所选索引形状不匹配:索引数组无法与该形状一起广播。
  • 当访问 numpy 多维数组时,用于索引的数组需要具有相同的形状(行和列)。numpy 将有可能去广播,所以,若要为了实现不同维度的选择, 可分两步对数组进行选择。
  • (1) 例如我需要选择第 1 行和最后一行的第 1,3,4 列时,先选择行,再选择列。
  • (2) 先读取数组 a3_4 的第一行和最后一行,保存到 temp ,然后再筛选相应的列即可。
a3_4
#array([[ 0,  1,  2,  3],
#       [ 4,  5,  6,  7],
#       [ 8,  9, 10, 11]])
  • 那么,我们需要选择第 1 行和最后一行的第 1,3,4 列元素,操作步骤如下:
  • (1) 先选行。
temp = a3_4[[0,-1],:]
temp
#array([[ 0,  1,  2,  3],
#       [ 8,  9, 10, 11]])
  • (2) 再选择列。
temp[:,[0,2,3]]
temp
#array([[ 0,  2,  3],
#       [ 8, 10, 11]])
  • (3) 合并一条。
a3_4[[0,-1],:][:,[0,2,3]]
  • 但是,如果有一个一维数组长度是 1 时,这时又不会报错:
  • 比如说,如果我们需要提取第二行,第 1,3 列的数据。
a3_4[[1],[0,2]]
#array([4, 6])
  • 以上相当于 (1,0) 和 (1,2)。
  • 数组索引及切片的值更改会修改原数组
  • 一个标量赋值给一个索引/切片时,会自动改变/传播原始数组。
ar = np.arange(10)
print(ar)
ab = ar[:]
ar[5] = 100
print(ab)
#[0 1 2 3 4 5 6 7 8 9]
#[  0   1   2   3   4 100   6   7   8   9]
  • 可以使用复制操作。
ar = np.arange(10)
b = ar.copy()
  • 或者可以使用 b = np.array(ar)。
b[7:9] = 200
print('ar:',ar)
print('b:',b)

三、广播机制

  • 广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式, 对数组的算术运算通常在相应的元素上进行。
  • 如果两个数组 a 和 b 形状相同,即满足 a.shape == b.shape,那么 a*b 的结果就是 a 与 b 数组对应位相乘。这要求维数相同,且各维度的长度相同。
a = np.array([1,2,3,4]) 
b = np.array([10,20,30,40]) 
c = a * b 
print (c)
#[ 10  40  90 160]
  • 但如果两个形状不同的数组呢?它们之间就不能做算术运算了吗?
  • 当然不是!为了保持数组形状相同,NumPy 设计了一种广播机制, 这种机制的核心是对形状较小的数组,在横向或纵向上进行一定次数的重复,使其与形状较大的数组拥有相同的维度
a = np.array([[ 0, 0, 0],[10,10,10],[20,20,20],[30,30,30]])
b = np.array([1,2,3])
print(a + b)
  • 下面的图片展示了数组 b 如何通过广播来与数组 a 兼容。

在这里插入图片描述

  • 4x3 的二维数组与长为 3 的一维数组相加,等效于把数组 b 在二维上重复 4 次再运算。

1. 广播机制规则

  • 广播具有如下规则:
  • (1) 让所有输入数组都向其中形状最长的数组看齐,形状中不足的部分都通过在前面加 1 补齐。
  • (2) 输出数组的形状是输入数组形状的各个维度上的最大值。
  • (3) 如果输入数组的某个维度和输出数组的对应维度的长度相同或者其长度为 1 时,这个数组能够用来计算,否则出错。
  • (4) 当输入数组的某个维度的长度为 1 时,沿着此维度运算时都用此维度上的第一组值。
  • ** 为了更清楚的理解这些规则看,来看几个具体的示例**
  • 我们通过 np.ones() 生成一个全 1 数组,np.arange() 生成一个有规律元素的数组。
  • 两个数组的形状分别为 M.shape=(2,3),a.shape=(3,)。
  • 可以看到,根据规则 1,数组 a 的维度更小,所以在其左边补 1,变为 M.shape -> (2,3), a.shape -> (1,3)。
  • 根据规则 2,第一个维度不匹配,因此扩展这个维度以匹配数组:M.shape ->(2,3), a.shape -> (1,3)。
  • 现在两个数组的形状匹配了,可以看到它们的最终形状都为(2,3)。
M = np.ones((2,3))
print(M)
a = np.arange(3)
print(a)
M + a
#[[1. 1. 1.]
# [1. 1. 1.]]
#[0 1 2]
#array([[1., 2., 3.],
#       [1., 2., 3.]])
  • 我们通过 np.arange() 生成两个有规律元素数组,其中一个设置为三行一列,便于对广播机制进行验证。
  • 两个数组的形状设置为 a.shape=(3,1), b.shape=(3,)。
  • 规则 1 告诉我们,需要用 1 将 b 的形状补全:a.shape -> (3,1), b.shape -> (1,3)。
  • 规则 2 告诉我们,需要更新这两个数组的维度来相互匹配:a.shape -> (3,3), b.shape -> (3,3)
  • 因为结果匹配,所以这两个形状是兼容的。
a = np.arange(3).reshape((3,1))
print('a:',a)
b = np.arange(3)
print('b:',b)
a + b
#a: [[0]
# [1]
# [2]]
#b: [0 1 2]
#array([[0, 1, 2],
#       [1, 2, 3],
#       [2, 3, 4]])

2. 对于广播规则另一种简单理解

  • (1) 将两个数组的维度大小右对齐,然后比较对应维度上的数值。
  • (2) 如果数值相等或其中有一个为1或者为空,则能进行广播运算。
  • (3) 输出的维度大小为取数值大的数值。否则不能进行数组运算。
  • 数组 a 大小为(2, 3),数组 b 大小为 (1,),对其进行右对齐操作。
   2   31
----------2   3
  • 所以最后两个数组运算的输出大小为:(2, 3),下面对其进行代码验证。
a = np.arange(6).reshape(2, 3)
print('a:', a)
b = np.array([5])
print('b:',b)
c = a * b 
c
#a: [[0 1 2]
# [3 4 5]]
#b: [5]
#array([[ 0,  5, 10],
#       [15, 20, 25]])
  • 数组 a 大小为 (2, 1, 3),数组 b 大小为 (4, 1),对其进行右对齐操作。
 2  1  34  1
----------2  4  3
  • 所以最后两个数组运算的输出大小为:(2, 4, 3)。
a= np.arange(6).reshape(2, 1, 3)print('a:',a)
print('-'*10)
b = np.arange(4).reshape(4, 1)
print('b:',b)
print('-'*10)
c = a + b
print(c,c.shape)
#​a: [[[0 1 2]]
#
# [[3 4 5]]]
#----------
#b: [[0]
# [1]
# [2]
# [3]]
#----------
#[[[0 1 2]
#  [1 2 3]
#  [2 3 4]
#  [3 4 5]]
#
# [[3 4 5]
#  [4 5 6]
#  [5 6 7]
#  [6 7 8]]] (2, 4, 3)
  • 从这里能够看出:
  • (1) 两个数组右对齐以后,对应维度里的数值要么相等,要么有一个为 1,要么缺失取大值。
  • (2) 除此之外就会报错。像下面的两个数组就不能做运算。
  • 数组 a 大小为 (2, 1, 3),数组 b 大小为 (4, 2),对其进行右对齐操作。
 2  1  34  2
----------
  • 2 跟 3 不匹配,此时就不能做运算。
a = np.arange(6).reshape(2, 1, 3)
print('a:',a)
print('-'*10)
b = np.arange(8).reshape(4, 2)
print('b:',b)
print('-'*10)
a + b
#a: [[[0 1 2]]
#
# [[3 4 5]]]
#----------
#b: [[0 1]
# [2 3]
# [4 5]
# [6 7]]
#----------
#---------------------------------------------------------------------------
#ValueError                                Traceback (most recent call last)
#<ipython-input-68-2ebfaa0877fb> in <module>
#      9 print('-'*10)
#     10 # 运行报错
#---> 11 a + b
#
#ValueError: operands could not be broadcast together with shapes (2,1,3) (4,2) 
  • 广播机制能够处理不同大小的数组,数组之间必须满足广播的规则,否则就会报错。
  • 事实上,相同大小的数组运算也遵循广播机制。

相关文章:

Python 之 NumPy 切片索引和广播机制

文章目录一、切片和索引1. 一维数组2. 二维数组二、索引的高级操作1. 整数数组索引2. 布尔数组索引三、广播机制1. 广播机制规则2. 对于广播规则另一种简单理解一、切片和索引 ndarray 对象的内容可以通过索引或切片来访问和修改&#xff08;&#xff09;&#xff0c;与 Pytho…...

Redis【包括Redis 的安装+本地远程连接】

Redis 一、为什么要用缓存&#xff1f; 缓存定义 缓存是一个高速数据交换的存储器&#xff0c;使用它可以快速的访问和操作数据。 程序中的缓存 在我们程序中&#xff0c;如果没有使用缓存&#xff0c;程序的调用流程是直接访问数据库的&#xff1b; 如果多个程序调用一个数…...

深度学习训练营_第P3周_天气识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f366; 参考文章&#xff1a;Pytorch实战 | 第P3周&#xff1a;彩色图片识别&#xff1a;天气识别**&#x1f356; 原作者&#xff1a;K同学啊|接辅导、项目定制**␀ 本次实验有两个新增任务&…...

“华为杯”研究生数学建模竞赛2006年-【华为杯】C题:维修线性流量阀时的内筒设计问题(附获奖论文及matlab代码)

赛题描述 油田采油用的油井都是先用钻机钻几千米深的孔后,再利用固井机向四周的孔壁喷射水泥砂浆得到水泥井管后形成的。固井机上用来控制砂浆流量的阀是影响水泥井管质量的关键部件,但也会因磨损而损坏。目前我国还不能生产完整的阀体,固井机仍依赖进口。由于损坏的内筒已…...

数据结构:带环单链表基础OJ练习笔记(leetcode142. 环形链表 II)(leetcode三题大串烧)

目录 一.前言 二.leetcode160. 相交链表 1.问题描述 2.问题分析与求解 三.leetcode141. 环形链表 1.问题描述 2.代码思路 3.证明分析 下一题会用到的重要小结论&#xff1a; 四.leetcode142. 环形链表 II 1.问题描述 2.问题分析与求解 Judgecycle接口&#xf…...

数模美赛如何找数据 | 2023年美赛数学建模必备数据库

2023美赛资料分享/思路答疑群&#xff1a;322297051 欧美相关统计数据&#xff08;一般美赛这里比较多&#xff09; 1、http://www.census.gov/ 美国统计局&#xff08;统计调查局或普查局&#xff09;官方网站 The Census Bureau Web Site provides on-line access to our …...

SSTI漏洞原理及渗透测试

模板引擎&#xff08;Web开发中&#xff09; 是为了使 用户界面 和 业务数据&#xff08;内容&#xff09;分离而产生的&#xff0c;它可以生成特定格式的文档&#xff0c; 利用模板引擎来生成前端的HTML代码&#xff0c;模板引擎会提供一套生成HTML代码的程序&#xff0c;之后…...

【算法基础】高精度除法

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前是C语言 算法学习者 ✈️专栏&#xff1a;【C/C】算法 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac…...

optimizer.zero_grad(), loss.backward(), optimizer.step()的理解及使用

optimizer.zero_grad&#xff0c;loss.backward&#xff0c;optimizer.step用法介绍optimizer.zero_grad()&#xff1a;loss.backward()&#xff1a;optimizer.step()&#xff1a;用法介绍 这三个函数的作用是将梯度归零&#xff08;optimizer.zero_grad()&#xff09;&#x…...

融资、量产和一栈式布局,这家Tier 1如此备战高阶智驾决赛圈

作者 | Bruce 编辑 | 于婷从早期的ADAS&#xff0c;到高速/城市NOA&#xff0c;智能驾驶的竞争正逐渐升级&#xff0c;这对于车企和供应商的核心技术和产品布局都是一个重要的考验。 部分智驾供应商已经在囤积粮草&#xff0c;响应变化。 2023刚一开年&#xff0c;智能驾驶领域…...

centos7.8安装oralce11g

文章目录环境安装文件准备添加用户操作系统环境配置解压安装问题解决创建用户远程连接为了熟悉rman备份操作&#xff0c;参照大神的博客在centos中安装了一套oracle11g&#xff0c;将安装步骤记录如下环境安装文件准备 这里准备一台centos7.8 虚拟机 配置ip 192.168.18.100 主…...

【蓝桥杯集训·每日一题】AcWing 3956. 截断数组

文章目录一、题目1、原题链接2、题目描述二、解题报告1、思路分析2、时间复杂度3、代码详解三、知识风暴一维前缀和一、题目 1、原题链接 3956. 截断数组 2、题目描述 给定一个长度为 n 的数组 a1,a2,…,an。 现在&#xff0c;要将该数组从中间截断&#xff0c;得到三个非空子…...

万丈高楼平地起:Linux常用命令

目录 系统管理命令 man命令 ls命令 cd命令 useradd命令 passwd命令 free命令 whoami命令 ps命令 date命令 pwd命令 shutdown命令 文件目录管理命令 touch命令 cat命令 mkdir命令 rm命令 cp命令 mv命令 find命令 more指令 less指令 head指令 tail指令 …...

Linux(Linux的连接使用)

连接Linux我们一般使用CRT或者Xshell工具进行连接使用。 如CRT使用SSH的方式 输出主机&#xff0c;账户&#xff0c;密码那些就可以连接上了。 Linux系统是一个文件型操作系统&#xff0c;有一句话说Linux的一切皆是文件。Linux系统的启动大致有下面几个步骤 Linux系统有7个运…...

Unity中画2D图表(2)——用XChart包绘制散点分布图 + 一条直线方程

散点图用于显示关系。 对于 【相关性】 &#xff0c;散点图有助于显示两个变量之间线性关系的强度。 对于 【回归】 &#xff0c;散点图常常会添加拟合线。 举例1&#xff1a;你可以展示【年降雨量】与【玉米亩产量】的关系 举例2&#xff1a;你也可以分析各个【节假日】与【大…...

Go 排序包 sort

写在前面的使用总结&#xff1a; 排序结构体 实现Len&#xff0c;Less&#xff0c;Swap三个函数 package main import ( "fmt" "sort") type StuScore struct { name string score int } type StuScores []StuScore func (s StuScores) Len(…...

Java Email 发HTML邮件工具 采用 freemarker模板引擎渲染

Java Email 发HTML邮件工具 采用 freemarker模板引擎 1.常用方式对比 Java发送邮件有很多的实现方式 第一种&#xff1a;Java 原生发邮件mail.jar和activation.jar <!-- https://mvnrepository.com/artifact/javax.mail/mail --> <dependency><groupId>jav…...

CNI 网络流量分析(六)Calico 介绍与原理(二)

文章目录CNI 网络流量分析&#xff08;六&#xff09;Calico 介绍与原理&#xff08;二&#xff09;CNIIPAM指定 IP指定非 IPAM IPCNI 网络流量分析&#xff08;六&#xff09;Calico 介绍与原理&#xff08;二&#xff09; CNI 支持多种 datapath&#xff0c;默认是 linuxDa…...

短视频标题的几种类型和闭坑注意事项

目录 短视频标题的几种类型 1、悬念式 2、蹭热门式 3、干货式 4、对比式方法 5、总分/分总式方法 6、挑战式方式 7、启发激励式 8、讲故事式 02注意事项 1、避免使用冷门、生僻词汇 标题是点睛之笔&#xff0c;核心是视频内容 短视频标题的几种类型 1、悬念式 通过…...

操作系统——1.操作系统的概念、定义和目标

目录 1.概念 1.1 操作系统的种类 1.2电脑的组成 1.3电脑组成的介绍 1.4操作系统的概念&#xff08;定义&#xff09; 2.操作系统的功能和目标 2.1概述 2.2 操作系统作为系统资源的管理者 2.3 操作系统作为用户和计算机硬件间的接口 2.3.1用户接口的解释 2.3.2 GUI 2.3.3接…...

【html弹框拖拽和div拖拽功能】原生html页面引入vue语法后通过自定义指令简单实现div和弹框拖拽功能

前言 这是html版本的。只是引用了vue的语法。 这是很多公司会出现的一种情况&#xff0c;就是原生的页面&#xff0c;引入vue的语法开发 这就导致有些vue上很简单的功能。放到这里需要转换一下 以前写过一个vue版本的帖子&#xff0c;现在再加一个html版本的。 另一个vue版本…...

2023新华为OD机试题 - 计算网络信号(JavaScript) | 刷完必过

计算网络信号 题目 网络信号经过传递会逐层衰减,且遇到阻隔物无法直接穿透,在此情况下需要计算某个位置的网络信号值。 注意:网络信号可以绕过阻隔物 array[m][n] 的二维数组代表网格地图,array[i][j] = 0代表 i 行 j 列是空旷位置;array[i][j] = x(x 为正整数)代表 i 行 …...

27.边缘系统的架构

文章目录27 Architecures for the Edge 边缘系统的架构27.1 The Ecosystem of Edge-Dominant Systems 边缘主导系统的生态系统27.2 Changes to the Software Development Life Cycle 软件开发生命周期的变化27.3 Implications for Architecture 对架构的影响27.4 Implications …...

机器学习强基计划8-1:图解主成分分析PCA算法(附Python实现)

目录0 写在前面1 为什么要降维&#xff1f;2 主成分分析原理3 PCA与SVD的联系4 Python实现0 写在前面 机器学习强基计划聚焦深度和广度&#xff0c;加深对机器学习模型的理解与应用。“深”在详细推导算法模型背后的数学原理&#xff1b;“广”在分析多个机器学习模型&#xf…...

Hudi-集成Spark之spark-shell 方式

Hudi集成Spark之spark-shell 方式 启动 spark-shell &#xff08;1&#xff09;启动命令 #针对Spark 3.2 spark-shell \--conf spark.serializerorg.apache.spark.serializer.KryoSerializer \--conf spark.sql.catalog.spark_catalogorg.apache.spark.sql.hudi.catalog.Hoo…...

Python爬虫:从js逆向了解西瓜视频的下载链接的生成

前言 最近花费了几天时间,想获取西瓜视频这个平台上某个视频的下载链接,运用js逆向进行获取。其实,如果小编一开始就注意到这一点(就是在做js逆向时,打了断点之后,然后执行相关代码,查看相关变量的值,结果一下子就蹦出很多视频相关的数据,查看了网站下的相关api链接,也…...

Numpy-如何对数组进行切割

前言 本文是该专栏的第24篇,后面会持续分享python的数据分析知识,记得关注。 继上篇文章,详细介绍了使用numpy对数组进行叠加。本文再详细来介绍,使用numpy如何对数组进行切割。说句题外话,前面有重点介绍numpy的各个知识点。 感兴趣的同学,可查看笔者之前写的详细内容…...

Python之字符串精讲(下)

前言 今天继续讲解字符串下半部分&#xff0c;内容包括字符串的检索、大小写转换、去除字符串中空格和特殊字符。 一、检索字符串 在Python中&#xff0c;字符串对象提供了很多用于字符串查找的方法&#xff0c;主要给大家介绍以下几种方法。 1. count() 方法 count() 方法…...

Python图像卡通化animegan2-pytorch实例演示

先看下效果图&#xff1a; 左边是原图&#xff0c;右边是处理后的图片&#xff0c;使用的 face_paint_512_v2 模型。 项目获取&#xff1a; animegan2-pytorch 下载解压后 cmd 可进入项目地址的命令界面。 其中 img 是我自己建的&#xff0c;用于存放图片。 需要 torch 版本 …...

谢希仁版《计算机网络》期末总复习【完结】

文章目录说明第一章 计算机网络概述计算机网络和互联网网络边缘网络核心分组交换网的性能网络体系结构控制平面和数据平面第二章 IP地址分类编址子网划分无分类编址特殊用途的IP地址IP地址规划和分配第三章 应用层应用层协议原理万维网【URL / HTML / HTTP】域名系统DNS动态主机…...

做外贸出口的网站/网站策划是干什么的

%86时出现报错 Error in invoking target agent nmhs of makefile 解决方案在makefile中添加链接libnnz11库的参数修改$ORACLE_HOME/sysman/lib/ins_emagent.mk&#xff0c;将$(MK_EMAGENT_NMECTL)修改为&#xff1a;$(MK_EMAGENT_NMECTL) -lnnz11建议修改前备份原始文件[ora…...

广告公司资质/沈阳seo技术

squishfroglogic 宣布 &#xff0c;Squash现在支持基于新的Eclipse 3.6Helios版本的Java Rich Client Platform应用程序的自动化测试。 Squish for Java是一种跨平台的功能GUI和回归测试工具&#xff0c;用于为Java SWT / RCP和AWT / Swing应用程序创建和执行自动化GUI测试。 …...

wordpress图片轮播插件/网站维护的内容有哪些

1、使用 gitlab 创建合并请求 master 合并到 branch_test --> compare branches and continue --> submit merge request 提示:合并冲突。 2、使用 idea 打开项目。 (1)执行:git fetch origin (2)切换到 master 分支,更新到最新版本。 (3)切换到 branch_test 分支,更…...

省机关事务局网站建设管理情况/常州seo招聘

1、在测试列表中插入一个多行文本字段&#xff0c;名字叫做Content&#xff0c;如下图&#xff1a; 2、在Content字段里&#xff0c;添加一个Link&#xff0c;如下图&#xff1a; 3、尝试输入Notes格式的Link&#xff0c;如下图&#xff1a; 4、点击OK的时候&#xff0c;弹出消…...

博彩网站如何做的充值/怎么在百度上注册店铺

ls 命令的含义是list显 示当前目录中的文件名字。注意不加参数它显示除隐藏文件外的所有文件及目录的名字。ls是Linux/Ubuntu中 经常用到的一个命令,也是一个非常基本的命令。 1、文件名颜色的含义 1&#xff09;默认色代表普通文件。例&#xff1a;install.log 2&#xff09;绿…...

济南市住房建设网站/seo推广教程seo推广技巧

TensorFlow2.0高阶操作演示合并与分割数据统计张量排序填充与复制张量限幅高阶操作合并与分割 tf.concat([a, b], axis) 沿着axis轴&#xff08;维度&#xff09;拼接若干个张量&#xff0c;必须保证参与拼接的各个张量除需要拼接的维度其他维度必须一致&#xff0c;concat不会…...