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

Python编程进阶知识之第三课处理数据(numpy)

简介

        在 Python 数据处理领域,作为数据分析三剑客之一的numpy可是不可或缺的重要工具,它能让数据运算变得更高效、更简洁。这节课会从 numpy 的基础概念讲起,逐步深入到数组操作、数据运算、统计分析等核心知识点。不管你是想提升数据处理效率,还是为后续的数据分析、机器学习打下基础。

        NumPy的广泛应用范围包括数据处理、科学研究、机器学习、图像处理、信号处理等各种领域。以下是Numpy的一些特点:

  • 高效运算:基于 C 语言实现,处理大型数组和矩阵运算速度远超 Python 原生列表。
  • 多维数组:核心是 ndarray 对象,支持多维数组,方便存储和操作结构化数据。
  • 丰富函数:内置大量数学、统计、线性代数等函数,简化数据处理步骤。
  • 内存高效:数组元素类型统一,内存占用低,适合处理海量数据。
  • 集成性强:是 pandas、matplotlib 等数据科学库的基础,便于协同使用。

 1.安装Numpy

        打开cmd,安装指定版本,使用清华园镜像园下载会更快

pip install numpy ==1.23.5 -i https://pypi.tuna.tsinghua.edu.cn/simple

        出现 Successfully installed numpy-1.23.5说明安装成功,可以pip list查看自己安装的第三方库。

 2.创建数组

       学习 NumPy,首先要建立对其核心对象 —— 数组(ndarray)的直观认知:既要清晰把握数组的结构形态,也要深入理解不同维度下数据的组织方式与类型特征。

1.创建一维数组

import numpy as np #导入numpy  as np
list1 = [1,2,3,4,5] #python自带的列表数据类型
print(list1)
v = np.array(list1)
print(v)
# 运行结果:
# [1, 2, 3, 4, 5]
# [1 2 3 4 5]

        在 NumPy 中,核心数据结构是 ndarray(全称为 N-dimensional array,即 N 维数组)。与 Python 原生列表不同,ndarray 打印时内部元素之间没有逗号分隔 —— 这一视觉特征也直观体现了它与列表在底层存储逻辑上的差异。

2.创建二维数组 (多个一维数组构成)

import numpy as np #导入numpy  as np
list1 = [1,2,3,4,5] #python自带的列表数据类型
m = np.array([list1,list1,list1])
print(m)
# 运行结果:
# [[1 2 3 4 5]
# [1 2 3 4 5]
# [1 2 3 4 5]]

 3.创建三维数组(多个二维数组构成)

import numpy as np #导入numpy  as np
list1 = [1,2,3,4,5] #python自带的列表数据类型
z = np.array([[list1,list1,list1],[list1,list1,list1],[list1,list1,list1]])
print(z)
# 运行结果:
# [[[1 2 3 4 5] # 第一个二维数组
#   [1 2 3 4 5]
#   [1 2 3 4 5]]
#
#  [[1 2 3 4 5] # 第二个二维数组
#   [1 2 3 4 5]
#   [1 2 3 4 5]]
#
#  [[1 2 3 4 5] # 第三个二维数组
#   [1 2 3 4 5]
#   [1 2 3 4 5]]]

 4.创建更高维度数组

import numpy as np #导入numpy  as np
list1 = [1,2,3,4,5] #python自带的列表数据类型
m = np.array([list1,list1,list1])
z = np.array([m,m,m])
y = np.array([z,z,z])
print(y)

         根据不同维度的数据并结合可视化页面理解更高维度的数组。

 5.创建全是0数组

        创建全零数组的用途是初始化一个具有特定形状和大小的数组,其中所有元素都设置为0。

# 创建全为0的数组
import numpy as np
a = np.zeros(5)
b = np.zeros((2, 2))  # zeros只能接受1个参数
c = np.zeros((3, 2, 2))
print(a, '\n', b, '\n', c)

 6.创建全是1数组

        创建全1数组的用途是初始化一个具有特定形状和大小的数组,其中所有元素都设置为1。

# 创建全为1的数组
import numpy as np
d = np.ones(5)
e = np.ones((2, 2))
f = np.ones((2, 2, 2))

 7.创建单位数组(矩阵)

        这个矩阵的特点是主对角线上的元素都为 1,而其他位置的元素都为 0。这种矩阵在数学领域被称作单位矩阵

import numpy as np
h = np.eye(5, 5)
print(h)

        运行结果 

[[1. 0. 0. 0. 0.][0. 1. 0. 0. 0.][0. 0. 1. 0. 0.][0. 0. 0. 1. 0.][0. 0. 0. 0. 1.]]

 8.创建有连续序列的数组 arange

        数组从o开始步长为3,所以创建出来数组元素就是0,3,6

import numpy as np
#1.arange(start, end, step) -> range(start, end, step)
# [左闭右开的区间]一次性产生规律的数据。
r1 = np.arange(0,9,3)
print(r1)
# 运行结果:[0 3 6]

9.创建有连续间隔的数组 linspace  

         在一个指定区间内按照指定的步长,将区间均等分,生成的是一个线段类型的数组。生成的线性间隔数据中,是有把区间的两端加进去的

#2.linspace(start, end, nums)
# [左右都是闭区间]
import numpy as np
r2 = np.linspace(0,1,21)
print(r2)
# 运行结果:[0.   0.05 0.1  0.15 0.2  0.25 0.3  0.35 0.4  0.45 0.5  0.55 0.6  0.65
# 0.7  0.75 0.8  0.85 0.9  0.95 1.  ]

10.创建值相同的数组

        np.full () 函数:此函数的作用是生成一个全部元素都相同的数组。它的主要参数有两个,一个是用于指定数组形状的shape,另一个是用于设定填充值的fill_value

import numpy as np #导入numpy  as np
# 创建全为3的数组   矩阵中全部填充指定的数据
g = np.full((2, 2, 2), 3)
print(g)

 数组形状为一个(2*2*2)的三维数组,数组里的每一个元素都会被设定为 3。

11.创建随机数组

        创建随机数组的用途是初始化一个具有特定形状和大小的数组,其中所有元素都是随机生成的。在处理一些需要模拟随机数据的情况时,随机数组可以用作占位符或测试数据。

生成整数随机数矩阵

# 生成随机数矩阵
import numpy as np
r3 = np.random.randint(0, 10, size=(5, 5))
print(r3)

参数:

0, 10:随机数范围为 [0, 10)(左闭右开)。

size=(5, 5):生成 5 行 5 列的矩阵。

[[2 8 3 7 9][1 5 4 0 6][3 7 2 9 1][5 0 8 4 3][6 9 2 7 5]]

 生成均匀分布的随机浮点数矩阵。

import numpy as np
r4 = np.random.rand(5, 5)
print(r4)

5, 5:直接指定矩阵形状(无需 size=)。

分布范围[0, 1)(左闭右开)。

生成正态分布(高斯分布)的随机浮点数矩阵。

import numpy as np
r5 = np.random.normal(5, 10, size=(5, 5))
print(r5)
"""
normal() -> 生成一些符合正态分布的数据
N~(0,1)
numpy.random.normal(loc=0.0, scale=1.0, size=None)
参数说明:
loc:正态分布的均值(期望值),决定了分布的中心位置,默认值为 0.0
scale:正态分布的标准差,决定了分布的离散程度,默认值为 1.0
size:输出数组的形状,可以是整数(表示一维数组长度)或元组(表示多维数组形状),默认值为 None(返回单个值)
"""

 2.数组的基本属性

1.数组的形状

import numpy as np #导入numpy  as np
list1 = [1,2,3,4,5] #python自带的列表数据类型
v = np.array(list1)
a = v.shape #查询数组的形状
print(a)
# 运行结果:(5,)
import numpy as np #导入numpy  as np
list1 = [1,2,3,4,5] #python自带的列表数据类型
m = np.array([list1,list1,list1])
a = m.shape#是描绘m矩阵的形状
print(a)
# 运行结果:(3, 5)

2.数组的维度

import numpy as np #导入numpy  as np
list1 = [1,2,3,4,5] #python自带的列表数据类型
v = np.array(list1)
b = v.ndim  #查询数组的维度
print(b)
# 运行结果:1
import numpy as np #导入numpy  as np
list1 = [1,2,3,4,5] #python自带的列表数据类型
m = np.array([list1,list1,list1])
b = m.ndim#表示数据的维度  2
print(b)
# 运行结果:2

3.数组中数据个数

import numpy as np #导入numpy  as np
list1 = [1,2,3,4,5] #python自带的列表数据类型
v = np.array(list1)
c = v.size  #查询数组中数据个数
print(c)
# 运行结果:5
import numpy as np #导入numpy  as np
list1 = [1,2,3,4,5] #python自带的列表数据类型
m = np.array([list1,list1,list1])
c = m.size
print(c)
# 运行结果:15

4.数组中的元素类型

查询数组中的元素类型,int8, int16, int32, int64: 表示不同长度的有符号整数。
import numpy as np #导入numpy  as np
list1 = [1,2,3,4,5] #python自带的列表数据类型
v = np.array(list1)
d = v.dtype
print(d)
# 运行结果:int32
import numpy as np #导入numpy  as np
list1 = [1,2,3,4,5] #python自带的列表数据类型
m = np.array([list1,list1,list1])
d = m.dtype
print(d)
# 运行结果:int32

3.数组的升降维

1.数组的升维

一维变二维[-1表示自己计算]【返回一个改变后的矩阵】a.reshape(newshape, order='C')a:要重新形状的数组。newshape:一个整数或者元组,用于定义新的形状。order:可选参数,指定元素在数组中的读取顺序。'C'意味着按行,'F'意味着按列,'A'意味着原顺序,'K'意味着元素在内存中的出现顺序。
import numpy as np
list1 = [1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8]#
v = np.array(list1) #一维
print(v)
r1 = v.reshape(4,4) #升二维 sheng # r1 = v.reshape(-1,4)
print(r1)
r2 = v.reshape(1,-1,2) #升三维
print(r2)
r3 = r1.reshape(2,2,4) #二维升三维
print(r3)

 2.数组的降维

三维降到二维

import numpy as np
list1 = [1, 2, 3, 4, 5, 6, 7, 8]
v = np.array(list1)
v = v.reshape(2, 2, 2)
print(v)# 将三维降到二维
r1 = v.reshape(1, 8)
print(r1)

高维降到一维

        flatten方法返回的是原数组的副本,这意味着对返回的一维数组所做的任何修改都不会影响原始的多维数组。

import numpy as np
list1 = [1, 2, 3, 4, 5, 6, 7, 8]
v = np.array(list1)
v = v.reshape(2, 2, 2)
r3 = v.flatten()  
print(r3)

        ravel方法(如果可能)返回的是原始数组的视图,因此对返回的一维数组所做的修改可能会影响原始的多维数组。这是因为ravel是改变了数组

import numpy as np
list1 = [1, 2, 3, 4, 5, 6, 7, 8]
v = np.array(list1)
v = v.reshape(2, 2, 2)
r2 = v.ravel()
print(r2)
shape也可以实现降维
list1 = [1, 2, 3, 4, 5, 6, 7, 8]
v = np.array(list1)
print(v)
v.shape = (2, 4)  # 通过直接对array数据的属性进行修改。
print(v)

4.数组元素选取与修改

1.一维数组

 创建数组

import numpy as np
array1 = np.arange(1, 9, 1)
print(array1)  # 输出: [1 2 3 4 5 6 7 8]
  • np.arange(1, 9, 1) 生成从 1 到 8 的整数数组(左闭右开,步长为 1)。

 选取单个元素

a = array1[1]  # 索引从0开始,选取第2个元素
print(a)  # 输出: 2

选取多个元素(通过索引列表)

b = array1[[1, 3, 5]]  # 选取索引为1、3、5的元素
print(b)  # 输出: [2 4 6]

切片操作

c = array1[0:6]  # 选取索引0到5的元素(左闭右开)
print(c)  # 输出: [1 2 3 4 5 6]

修改单个元素

print(array1)  # 输出: [1 2 3 4 5 6 7 8]
array1[0] = 10  # 将索引0的元素修改为10
print(array1)  # 输出: [10 2 3 4 5 6 7 8]

批量修改多个元素(通过索引列表)

array1[[1, 3, 5]] = 20  # 将索引1、3、5的元素统一修改为20
print(array1)  # 输出: [10 20 3 20 5 20 7 8]

批量修改切片范围

array1[0:6] = 100  # 将索引0到5的元素统一修改为100
print(array1)  # 输出: [100 100 100 100 100 100 7 8]

2.二维数组

创建二维数组

import numpy as np
array1 = np.arange(24).reshape(4, 6)
print(array1)
# 输出:
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]
#  [12 13 14 15 16 17]
#  [18 19 20 21 22 23]]
  • np.arange(24) 生成 0 到 23 的一维数组。
  • reshape(4, 6) 将一维数组转换为 4 行 6 列的二维数组。

选取单个元素

a = array1[1, 4]  # 第2行(索引1)第5列(索引4)
print(a)  # 输出: 10

选取整行元素

b = array1[3, :]  # 第4行(索引3)的所有列
print(b)  # 输出: [18 19 20 21 22 23]

选取多行元素

c = array1[0:2, :]  # 第1~2行(索引0~1)
d = array1[[0, 2], :]  # 第1行和第3行(索引0和2)
print(c)
# 输出:
# [[0 1 2 3 4 5]
#  [6 7 8 9 10 11]]
print(d)
# 输出:
# [[0 1 2 3 4 5]
#  [12 13 14 15 16 17]]

选取整列元素

e = array1[:, 3]  # 第4列(索引3)的所有行
print(e)  # 输出: [3 9 15 21]

选取多列元素

f = array1[:, 0:3]  # 第1~3列(索引0~2)
g = array1[:, [0, 3]]  # 第1列和第4列(索引0和3)
print(f)
# 输出:
# [[0 1 2]
#  [6 7 8]
#  [12 13 14]
#  [18 19 20]]
print(g)
# 输出:
# [[0 3]
#  [6 9]
#  [12 15]
#  [18 21]]

修改单个元素

array1[1, 4] = 100  # 将第2行第5列的元素改为100
print(array1)
# 输出:
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 100 11]
#  [12 13 14 15 16 17]
#  [18 19 20 21 22 23]]

修改整行元素

array1[3, :] = 100  # 将第4行的所有元素改为100
print(array1)
# 输出:
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 100 11]
#  [12 13 14 15 16 17]
#  [100 100 100 100 100 100]]array1[[0, 2], :] = 50  # 将第1行和第3行的所有元素改为50
print(array1)
# 输出:
# [[50 50 50 50 50 50]
#  [ 6  7  8  9 100 11]
#  [50 50 50 50 50 50]
#  [100 100 100 100 100 100]]

3.多维数组

     对于三维及更高维度的数组,索引和修改的核心逻辑是逐级定位,从最高维度开始,逐级指定索引或切片,arr[i, j, k]:从高到低指定各维度的位置。如三维数组选取元素
import numpy as nparray1 = np.arange(48).reshape(2, 4, 6)
print(array1)# 选取某个元素
# 首先确定选取哪一个二维数组
a = array1[1, 0, 0]
# array1 的结构示意:
[# 第一个二维数组(索引0)[[ 0,  1,  2,  3,  4,  5],[ 6,  7,  8,  9, 10, 11],[12, 13, 14, 15, 16, 17],[18, 19, 20, 21, 22, 23]],# 第二个二维数组(索引1) ← 第一步选中[[24, 25, 26, 27, 28, 29],  ← 第二步选中该行[30, 31, 32, 33, 34, 35],[36, 37, 38, 39, 40, 41],[42, 43, 44, 45, 46, 47]]
]# 最终选中元素:24(第二个二维数组的第一行第一列)

5.数组的组合

1.水平组合(hstack)

import numpy as np
# 生成基数组
array1 = np.arange(9).reshape(3, 3)
array2 = 2 * array1
print(array1)
print(array2)
a3 = np.hstack((array1, array2))
a4 = np.hstack((array2, array1))
a5 = np.hstack((array1, array2, array1))

在水平方向(列方向)拼接数组,要求行数相同

a3array1 和 array2 水平拼接

[[ 0  1  2  0  2  4][ 3  4  5  6  8 10][ 6  7  8 12 14 16]]

a4:顺序相反,array2 在前

[[ 0  2  4  0  1  2][ 6  8 10  3  4  5][12 14 16  6  7  8]]

a5:三个数组水平拼接

[[ 0  1  2  0  2  4  0  1  2][ 3  4  5  6  8 10  3  4  5][ 6  7  8 12 14 16  6  7  8]]

2. 垂直组合(vstack)

import numpy as np
# 生成基数组
array1 = np.arange(9).reshape(3, 3)
array2 = 2 * array1
print(array1)
print(array2)
a7 = np.vstack((array2, array1))

vstack:在垂直方向(行方向)拼接数组,要求列数相同

  • a7array2 和 array1 垂直拼接
[[ 0  2  4][ 6  8 10][12 14 16][ 0  1  2][ 3  4  5][ 6  7  8]]

3. 通用连接函数(concatenate)

concatenate:通过 axis 参数指定拼接方向:

  • axis=0:垂直方向(等效于 vstack)
  • axis=1:水平方向(等效于 hstack
import numpy as np
# 生成基数组
array1 = np.arange(9).reshape(3, 3)
array2 = 2 * array1
print(array1)
print(array2)
a6 = np.concatenate((array1, array2), axis=0)  a8 = np.concatenate((array1, array2), axis=1)

 6.数组的切割

1.水平切割(列方向)

import numpy as np
array1 = np.arange(16).reshape(4, 4)
print(array1)
# 输出:
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]
#  [12 13 14 15]]
a = np.hsplit(array1, 2)

将数组沿水平方向(列)平均分割为 2 个子数组。结果:

[array([[ 0,  1],[ 4,  5],[ 8,  9],[12, 13]]),array([[ 2,  3],[ 6,  7],[10, 11],[14, 15]])]

等同于: 

b = np.split(array1, 2, axis=1)

2.垂直切割(行方向)

import numpy as np
array1 = np.arange(16).reshape(4, 4)
print(array1)
# 输出:
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]
#  [12 13 14 15]]
c = np.vsplit(array1, 2)

将数组沿垂直方向(行)平均分割为 2 个子数组。结果:

[array([[0, 1, 2, 3],[4, 5, 6, 7]]),array([[ 8,  9, 10, 11],[12, 13, 14, 15]])]

等同于:

d = np.split(array1, 2, axis=0)

3.强制分割(无法等分的情况)

import numpy as np
array1 = np.arange(25).reshape(5, 5)
print(array1)
# 输出:
# [[ 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]]
g = np.array_split(array1, 3, axis=1)
h = np.array_split(array1, 3, axis=0)
[array([[ 0,  1],[ 5,  6],[10, 11],[15, 16],[20, 21]]),array([[ 2,  3],[ 7,  8],[12, 13],[17, 18],[22, 23]]),array([[ 4],[ 9],[14],[19],[24]])]
[array([[0, 1, 2, 3, 4],[5, 6, 7, 8, 9]]),array([[10, 11, 12, 13, 14],[15, 16, 17, 18, 19]]),array([[20, 21, 22, 23, 24]])]

 7.数组的深拷贝与浅拷贝

1.浅拷贝

  • 浅拷贝机制
    • array2 = array1 并未创建新数组,而是让 array2 指向 array1 的内存地址。
    • 共享数据:修改 array2 会直接影响 array1,反之亦然。
import numpy as np
array1 = np.array([1, 2, 3])
array2 = array1  # 浅拷贝(仅复制引用)# 修改array2的元素
array2[0] = 100print(array2)  # 输出: [100   2   3]
print("####################")
print(array1)  # 输出: [100   2   3]

 2.深拷贝

  • 深拷贝机制
    • array1.copy() 创建一个新数组 array3,并复制原始数据到新内存空间。
    • 数据独立:修改 array3 不会影响 array1,反之亦然。
import numpy as np
array3 = array1.copy()  # 深拷贝(创建独立数组)# 修改array3的元素
array3[0] = 10print(array3)  # 输出: [10   2   3]
print("####################")
print(array1)  # 输出: [100   2   3](未受影响)

8.数组的算数运算

        数组的算数运算跟数值的算数运算差不多,只要两个或多个数组对应位置进行算数运算

import  numpy as np
array1 = np.array([[1, 2], [3, 4]])
array2=2*array1
print(array1)
print(array2)#数组的加法【对应位置的元素求和】
print(array1+array2)#数组的减法【对应位置的元素相减】
print(array1-array2)#数组的乘法【对应位置的元素相乘】
print(array1*array2)#数组的除法【对应位置的元素相除】
print(array1/array2)#数组的取余【%】
print(array2%array1)#数组的取整【//】
print(array1//array2)

 9.数组的数据统计

import numpy as nparray1 = np.random.normal(size=(3, 3))
print(array1)# 一些函数
# 求方差
print(array1.var())# 求标准差
a = array1.std()# 求均值
b = array1.mean()# 求和
c = array1.sum()# 求中位数
# array1.median()
d = np.median(array1)# 求和运算
# 对矩阵的行求和
e = array1.sum(axis=1)
# 对矩阵的列进行求和
f = array1.sum(axis=0)

10.矩阵的运算

import numpy as np# 生成两个基数组
a = np.arange(4).reshape(2, 2)
b = a.copy()# 矩阵的运算
# 加减乘除(求逆)
# 加减 -> 对应元素加减# 矩阵的乘法【点乘】
# a * b
a1 = a.dot(b)
a2 = np.dot(a, b)# 矩阵求逆
"""
inv():
并不是所有的矩阵都有逆;
即使你没有逆,给你一个逆【伪逆】
"""
a3 = np.linalg.inv(a)a4 = a.dot([[-1.5, 0.5],[1., 0.]])
print(a4)

11.保存和加载数组

# numpy.loadtxt(): 从文本文件中加载数据。这个函数假定文件中的每一行都有相同数量的值,
# 你可以使用 delimiter 参数指定分隔符,如逗号、制表符等。例如:
import numpy as npdata = np.loadtxt('datingTestSet2.txt', delimiter='\t')# csv格式为,
print(data)# 将数组保存到txt文件中
import numpy as nparray = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])  # 创建一个 NumPy 数组
np.savetxt('array.txt', array)  # 使用 savetxt() 将数组保存到文本文件中

总结:

        NumPy 是数据处理的 “基础设施”,掌握其核心操作(数组创建、维度调整、元素操作、运算统计)是后续学习 Pandas 数据分析、Scikit-learn 机器学习的前提。建议结合实际场景练习(如用随机数组模拟销售数据,计算月度均值;用矩阵运算处理图像像素),在实践中熟悉这些技能。numpy知识点比较繁琐,但是都是比较简单理解的,认真琢磨明白numpy有哪些操作就行,并不需要刻意去记忆,理解就好。

http://www.xdnf.cn/news/1165735.html

相关文章:

  • 学习pwn需要的基本汇编语言知识
  • MCP vs 传统集成方案:REST API、GraphQL、gRPC的终极对比
  • nodejs:告别全局安装,npx 命令详解及其与 npm 的区别
  • npm全局安装后,依然不是内部或外部命令,也不是可运行的程序或批处理文件
  • Go语言切片(Slice)与数组(Array)深度解析:避坑指南与最佳实践
  • rocky9-zabbix简单部署
  • Vue底层换成啥了?如何更新DOM的?
  • 基于单片机智能消毒柜设计
  • 【IDEA】如何在IDEA中通过git创建项目?
  • 原型链污染
  • uniapp请求封装上传
  • uniapp app打包流程
  • 【Python办公】Excel工作表拆分工具(按照sheet进行拆分-calamine-极速版)
  • NIO技术原理以及应用(AI)
  • Kotlin介绍
  • 重构创作边界:川翔云电脑 - UE5云端超算引擎​
  • Kafka——揭开神秘的“位移主题”面纱
  • Springboot+vue个人健康管理系统的设计与实现
  • 【电影剖析】千钧一发
  • ISPDiffuser文章翻译理解
  • 深入解析MIPI C-PHY (二)C-PHY三线魔术:如何用6种“符号舞步”榨干每一滴带宽?
  • uni-api交互反馈组件(showToast)的用法
  • SmartETL循环流程的设计与应用
  • 《Linux 环境下 Nginx 多站点综合实践:域名解析、访问控制与 HTTPS 加密部署》​
  • 【金仓数据库产品体验官】_KingbaseES(SQLServer兼容版)保姆级安装教程
  • AC身份认证实验之AAA服务器
  • Linux中ELF区域与文件偏移量的关系
  • 【牛客算法】小美的排列询问
  • DL00691-基于深度学习的轴承表面缺陷目标检测含源码python
  • Python可迭代归约函数深度解析:从all到sorted的进阶指南