《零基础实践深度学习》1.7 附录:NumPy介绍 ndarray

2024-02-14 12:20

本文主要是介绍《零基础实践深度学习》1.7 附录:NumPy介绍 ndarray,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

📌 原文链接: https://aistudio.baidu.com/...

1.7 附录:NumPy介绍

NumPy(Numerical Python的简称)是高性能科学计算和数据分析的基础包。使用飞桨构建神经网络模型时,通常会使用NumPy实现数据预处理和一些模型指标的计算,飞桨中的Tensor数据可以很方便的和ndarray数组进行相互转换。

NumPy具有如下功能:

  • ndarray数组:一个具有矢量算术运算和复杂广播能力的多维数组,具有快速且节省空间的特点。
  • 整组数据进行快速运算的标准数学函数(无需编写循环)。
  • 线性代数、随机数生成以及傅里叶变换功能。
  • 读写磁盘数据、操作内存映射文件。

本质上,NumPy期望用户在执行“向量”操作时,像使用“标量”一样轻松。读者可以先在本机上运行如下代码,感受一下NumPy的便捷。

In [3]

>>> import numpy as np 
>>> a = np.array([1,2,3,4]) 
>>> b = np.array([10,20,30,40]) 
>>> c = a + b 
>>> print (c)

[11 22 33 44]

1.7.1 ndarray数组

ndarray数组是NumPy的基础数据结构,可以灵活、高效地处理多个元素的操作。本节主要从如下五部分展开介绍:

(1)为什么引入ndarray数组

(2)如何创建ndarray数组

(3)ndarray数组的基本运算

(4)ndarray数组的切片和索引

(5)ndarray数组的统计运算

1.7.1.1 为什么引入ndarray数组

Python中的List列表也可以非常灵活的处理多个元素的操作,但效率却非常低。与之比较,ndarray数组具有如下特点:

  • ndarray数组中所有元素的数据类型相同、数据地址连续,批量操作数组元素时速度更快。而list列表中元素的数据类型可能不同,需要通过寻址方式找到下一个元素。
  • ndarray数组支持广播机制,矩阵运算时不需要写for循环
  • NumPy底层使用C语言编写,内置并行计算功能,运行速度高于Python代码。

下面通过几个案例体会一下,在完成同一个任务时,使用ndarray数组和List列表的差异。

案例1:实现a+1的计算

In [3]

# Python原生的list
# 假设有两个list
a = [1, 2, 3, 4, 5]
b = [2, 3, 4, 5, 6]# 完成如下计算
# 对a的每个元素 + 1
# a = a + 1 不能这么写,会报错
# a[:] = a[:] + 1 也不能这么写,也会报错
for i in range(5):a[i] = a[i] + 1
a

[2, 3, 4, 5, 6]

In [4]

# 使用ndarray
import numpy as np
a = np.array([1, 2, 3, 4, 5])
a = a + 1
a

array([2, 3, 4, 5, 6])

案例2:实现c=a+b的计算

In [5]

# 计算 a和b中对应位置元素的和,是否可以这么写?
a = [1, 2, 3, 4, 5]
b = [2, 3, 4, 5, 6]
c = a + b
# 检查输出发现,不是想要的结果
c

[1, 2, 3, 4, 5, 2, 3, 4, 5, 6]

In [6]

# 使用for循环,完成两个list对应位置元素相加
c = []
for i in range(5):c.append(a[i] + b[i])
c

[3, 5, 7, 9, 11]

In [7]

# 使用numpy中的ndarray完成两个ndarray相加
import numpy as np
a = np.array([1, 2, 3, 4, 5])
b = np.array([2, 3, 4, 5, 6])
c = a + b 
c

array([ 3, 5, 7, 9, 11])

通过案例1和案例2可以看出,在不写for循环的情况下,ndarray数组就可以非常方便的完成数学计算。在编写矢量或者矩阵的程序时,可以像编写普通数值一样,使得代码极其简洁。另外,ndarray数组还提供了广播机制,它会按一定规则自动对数组的维度进行扩展以完成计算,如案例3所示,1维数组和2维数组进行相加操作,ndarray数组会自动扩展1维数组的维度,然后再对每个位置的元素分别相加。

案例3:实现1维数组和2维数组相加的操作

In [8]

# 自动广播机制,1维数组和2维数组相加# 二维数组维度 2x5
# array([[ 1,  2,  3,  4,  5],
#         [ 6,  7,  8,  9, 10]])
d = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
# c是一维数组,维度5
# array([ 4,  6,  8, 10, 12])
c = np.array([ 4,  6,  8, 10, 12])
e = d + c
e

array([[ 5, 8, 11, 14, 17],

[10, 13, 16, 19, 22]])

1.7.1.2 创建ndarray数组

创建ndarray数组最简单的方式就是使用array函数,它接受一切序列型的对象(包括其他数组),然后产生一个新的含有传入数据的NumPy数组。下面通过示例展示arrayarangezerosones四个主要函数的实现方法。

  • array创建嵌套序列(比如由一组等长列表组成的列表),并转换为一个多维数组。

In [9]

# 导入numpy
import numpy as np# 从list创建array 
a = [1,2,3,4,5,6]  # 创建简单的列表
b = np.array(a)    # 将列表转换为数组
b

array([1, 2, 3, 4, 5, 6])

  • arange创建元素从0到10依次递增2的数组。

In [10]

# 通过np.arange创建
# 通过指定start, stop (不包括stop),interval来产生一个1维的ndarray
a = np.arange(0, 10, 2)
a

array([0, 2, 4, 6, 8])

  • zeros :创建指定长度或者形状的全0数组

In [79]

# 创建全0的ndarray
a = np.zeros([3,3])
a

array([[0., 0., 0.],

[0., 0., 0.],

[0., 0., 0.]])

  • ones :创建指定长度或者形状的全1数组。

In [80]

# 创建全1的ndarray
a = np.ones([3,3])
a

array([[1., 1., 1.],

[1., 1., 1.],

[1., 1., 1.]])

1.7.1.3 查看ndarray数组的属性

ndarray的属性包括shapedtypesizendim等,通过如下代码可以查看ndarray数组的属性。

  • shape :数组的形状 ndarray.shape,1维数组 ( N , ) (N, ) ,2维数组 ( M , N ) (M, N) , 3 维数组( M , N , K ) 3维数组(M, N, K) 。
  • dtype :数组的数据类型
  • size :数组中包含的元素个数 ndarray.size ,其大小等于各个维度的长度的乘积。
  • ndim :数组的维度大小 ndarray.ndim , 其大小等于 ndarray.shape 所包含元素的个数。

In [81]

a = np.ones([3, 3])
print('a, dtype: {}, shape: {}, size: {}, ndim: {}'.format(a.dtype, a.shape, a.size, a.ndim))

a, dtype: float64, shape: (3, 3), size: 9, ndim: 2

In [82]

import numpy as np
b = np.random.rand(10, 10)
b.shape

(10, 10)

In [83]

b.size

In [84]

b.ndim

In [85]

b.dtype

dtype('float64')

1.7.1.4 改变ndarray数组的数据类型和形状

创建ndarray之后,可以对其数据类型或形状进行修改,代码实现如下:

In [86]

# 转化数据类型
b = a.astype(np.int64)
print('b, dtype: {}, shape: {}'.format(b.dtype, b.shape))# 改变形状
c = a.reshape([1, 9])
print('c, dtype: {}, shape: {}'.format(c.dtype, c.shape))

b, dtype: int64, shape: (3, 3)

c, dtype: float64, shape: (1, 9)

1.7.1.5 ndarray数组的基本运算

ndarray数组可以像普通的数值型变量一样进行加减乘除操作,主要包含如下两种运算:标量和ndarray数组之间的运算、两个ndarray数组之间的运算。

(1)标量和ndarray数组之间的运算

标量和ndarray数组之间的运算主要包括除法、乘法、加法和减法运算,代码实现如下:

In [87]

# 标量除以数组,用标量除以数组的每一个元素
arr = np.array([[1., 2., 3.], [4., 5., 6.]])
1. / arr

array([[1. , 0.5 , 0.33333333],

[0.25 , 0.2 , 0.16666667]])

In [88]

# 标量乘以数组,用标量乘以数组的每一个元素
arr = np.array([[1., 2., 3.], [4., 5., 6.]])
2.0 * arr

array([[ 2., 4., 6.],

[ 8., 10., 12.]])

In [89]

# 标量加上数组,用标量加上数组的每一个元素
arr = np.array([[1., 2., 3.], [4., 5., 6.]])
2.0 + arr

array([[3., 4., 5.],

[6., 7., 8.]])

In [90]

# 标量减去数组,用标量减去数组的每一个元素
arr = np.array([[1., 2., 3.], [4., 5., 6.]])
2.0 - arr

array([[ 1., 0., -1.],

[-2., -3., -4.]])

(2)两个ndarray数组之间的运算

两个ndarray数组之间的运算主要包括减法、加法、乘法、除法和开根号运算,代码实现如下:

In [91]

# 数组 减去 数组, 用对应位置的元素相减
arr1 = np.array([[1., 2., 3.], [4., 5., 6.]])
arr2 = np.array([[11., 12., 13.], [21., 22., 23.]])
arr1 - arr2

array([[-10., -10., -10.],

[-17., -17., -17.]])

In [92]

# 数组 加上 数组, 用对应位置的元素相加
arr1 = np.array([[1., 2., 3.], [4., 5., 6.]])
arr2 = np.array([[11., 12., 13.], [21., 22., 23.]])
arr1 + arr2

array([[12., 14., 16.],

[25., 27., 29.]])

In [93]

# 数组 乘以 数组,用对应位置的元素相乘
arr1 * arr2

array([[ 11., 24., 39.],

[ 84., 110., 138.]])

In [94]

# 数组 除以 数组,用对应位置的元素相除
arr1 / arr2

array([[0.09090909, 0.16666667, 0.23076923],

[0.19047619, 0.22727273, 0.26086957]])

In [95]

# 数组开根号,将每个位置的元素都开根号
arr ** 0.5

array([[1. , 1.41421356, 1.73205081],

[2. , 2.23606798, 2.44948974]])

1.7.1.6 ndarray数组的索引和切片

在编写模型过程中,通常需要访问或者修改ndarray数组某个位置的元素,则需要使用ndarray数组的索引。有些情况下可能需要访问或者修改一些区域的元素,则需要使用ndarray数组的切片

ndarray数组的索引和切片的使用方式与Python中的list类似。通过[ -n , n-1 ]的下标进行索引,通过内置的slice函数,设置其start,stopstep参数进行切片,从原数组中切割出一个新数组。ndarray数组的索引是一个内容丰富的主题,因为选取数据子集或单个元素的方式有很多。下面从一维数组和多维数组两个维度介绍索引和切片的方法。

(1)1维ndarray数组的索引和切片

从表面上看,一维数组跟Python列表的功能类似,它们重要区别在于:数组切片产生的新数组,还是指向原来的内存区域,数据不会被复制,视图上的任何修改都会直接反映到源数组上。将一个标量值赋值给一个切片时,该值会自动传播到整个选区。

In [96]

# 1维数组索引和切片
a = np.arange(30)
a[10]

In [97]

a = np.arange(30)
b = a[4:7]
b

array([4, 5, 6])

In [98]

# 将一个标量值赋值给一个切片时,该值会自动传播到整个选区。
a = np.arange(30)
a[4:7] = 10
a

array([ 0, 1, 2, 3, 10, 10, 10, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,

17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29])

In [99]

# 数组切片产生的新数组,还是指向原来的内存区域,数据不会被复制。
# 视图上的任何修改都会直接反映到源数组上。
a = np.arange(30)
arr_slice = a[4:7]
arr_slice[0] = 100
a, arr_slice

(array([ 0, 1, 2, 3, 100, 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]),

array([100, 5, 6]))

In [100]

# 通过copy给新数组创建不同的内存空间
a = np.arange(30)
arr_slice = a[4:7]
arr_slice = np.copy(arr_slice)
arr_slice[0] = 100
a, arr_slice

(array([ 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]),

array([100, 5, 6]))

(2)多维ndarray数组的索引和切片

多维ndarray数组的索引和切片具有如下特点:

  • 在多维数组中,各索引位置上的元素不再是标量而是多维数组
  • 逗号隔开的索引列表来选取单个元素
  • 在多维数组中,如果省略了后面的索引,则返回对象会是一个维度低一点的ndarray。

多维ndarray数组的索引代码实现如下所示。

In [101]

# 创建一个多维数组
a = np.arange(30)
arr3d = a.reshape(5, 3, 2)
arr3d

array([[[ 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]]])

In [102]

# 只有一个索引指标时,会在第0维上索引,后面的维度保持不变
arr3d[0]

array([[0, 1],

[2, 3],

[4, 5]])

In [103]

# 两个索引指标
arr3d[0][1]

array([2, 3])

In [104]

# 两个索引指标
arr3d[0, 1]

array([2, 3])

多维ndarray数组的切片代码如下所示。

In [105]

# 创建一个数组
a = np.arange(24)
a

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

17, 18, 19, 20, 21, 22, 23])

In [106]

# reshape成一个二维数组
a = a.reshape([6, 4])
a

array([[ 0, 1, 2, 3],

[ 4, 5, 6, 7],

[ 8, 9, 10, 11],

[12, 13, 14, 15],

[16, 17, 18, 19],

[20, 21, 22, 23]])

In [107]

# 使用for语句生成list
[k for k in range(0, 6, 2)]

[0, 2, 4]

In [108]

# 结合上面列出的for语句的用法
# 使用for语句对数组进行切片
# 下面的代码会生成多个切片构成的list
# k in range(0, 6, 2) 决定了k的取值可以是0, 2, 4
# 产生的list的包含三个切片
# 第一个元素是a[0 : 0+2],
# 第二个元素是a[2 : 2+2],
# 第三个元素是a[4 : 4+2]
slices = [a[k:k+2] for k in range(0, 6, 2)]
slices

[array([[0, 1, 2, 3],

[4, 5, 6, 7]]),

array([[ 8, 9, 10, 11],

[12, 13, 14, 15]]),

array([[16, 17, 18, 19],

[20, 21, 22, 23]])]

In [109]

slices[0]

array([[0, 1, 2, 3],

[4, 5, 6, 7]])

1.7.1.7 ndarray数组的统计方法

可以通过数组上的一组数学函数对整个数组或某个轴向的数据进行统计计算。主要包括如下统计方法:

  • mean :计算算术平均数,零长度数组的mean为NaN。
  • stdvar :计算标准差和方差,自由度可调(默认为n)。
  • sum :对数组中全部或某轴向的元素求和,零长度数组的sum为0。
  • maxmin :计算最大值和最小值
  • argminargmax :分别为最大和最小元素的索引
  • cumsum :计算所有元素的累加
  • cumprod :计算所有元素的累积

说明:

summean以及标准差std等聚合计算既可以当做数组的实例方法调用,也可以当做NumPy函数使用。


In [110]

# 计算均值,使用arr.mean() 或 np.mean(arr),二者是等价的
arr = np.array([[1,2,3], [4,5,6], [7,8,9]])
arr.mean(), np.mean(arr)

(5.0, 5.0)

In [111]

# 求和
arr.sum(), np.sum(arr)

(45, 45)

In [112]

# 求最大值
arr.max(), np.max(arr)

(9, 9)

In [113]

# 求最小值
arr.min(), np.min(arr)

(1, 1)

In [114]

# 指定计算的维度
# 沿着第1维求平均,也就是将[1, 2, 3]取平均等于2,[4, 5, 6]取平均等于5,[7, 8, 9]取平均等于8
arr.mean(axis = 1)

array([2., 5., 8.])

In [115]

# 沿着第0维求和,也就是将[1, 4, 7]求和等于12,[2, 5, 8]求和等于15,[3, 6, 9]求和等于18
arr.sum(axis=0)

array([12, 15, 18])

In [116]

# 沿着第0维求最大值,也就是将[1, 4, 7]求最大值等于7,[2, 5, 8]求最大值等于8,[3, 6, 9]求最大值等于9
arr.max(axis=0)

array([7, 8, 9])

In [117]

# 沿着第1维求最小值,也就是将[1, 2, 3]求最小值等于1,[4, 5, 6]求最小值等于4,[7, 8, 9]求最小值等于7
arr.min(axis=1)

array([1, 4, 7])

In [118]

# 计算标准差
arr.std()

2.581988897471611

In [119]

# 计算方差
arr.var()

6.666666666666667

In [120]

# 找出最大元素的索引
arr.argmax(), arr.argmax(axis=0), arr.argmax(axis=1)

(8, array([2, 2, 2]), array([2, 2, 2]))

In [121]

# 找出最小元素的索引
arr.argmin(), arr.argmin(axis=0), arr.argmin(axis=1)

(0, array([0, 0, 0]), array([0, 0, 0]))

1.7.2 随机数np.random

主要介绍创建ndarray随机数组以及随机打乱顺序、随机选取元素等相关操作的方法。

1.7.2.1 创建随机ndarray数组

创建随机ndarray数组主要包含设置随机种子、均匀分布和 正态分布三部分内容,代码如下所示。

(1)设置随机数种子

In [122]

# 可以多次运行,观察程序输出结果是否一致
# 如果不设置随机数种子,观察多次运行输出结果是否一致
np.random.seed(10)
a = np.random.rand(3, 3)
a

array([[0.77132064, 0.02075195, 0.63364823],

[0.74880388, 0.49850701, 0.22479665],

[0.19806286, 0.76053071, 0.16911084]])

(2)均匀分布

In [123]

# 生成均匀分布随机数,随机数取值范围在[0, 1)之间
a = np.random.rand(3, 3)
a

array([[0.08833981, 0.68535982, 0.95339335],

[0.00394827, 0.51219226, 0.81262096],

[0.61252607, 0.72175532, 0.29187607]])

In [124]

# 生成均匀分布随机数,指定随机数取值范围和数组形状
a = np.random.uniform(low = -1.0, high = 1.0, size=(2,2))
a

array([[ 0.83554825, 0.42915157],

[ 0.08508874, -0.7156599 ]])

(3)正态分布

In [125]

# 生成标准正态分布随机数
a = np.random.randn(3, 3)
a

array([[ 1.484537 , -1.07980489, -1.97772828],

[-1.7433723 , 0.26607016, 2.38496733],

[ 1.12369125, 1.67262221, 0.09914922]])

In [126]

# 生成正态分布随机数,指定均值loc和方差scale
a = np.random.normal(loc = 1.0, scale = 1.0, size = (3,3))
a

array([[2.39799638, 0.72875201, 1.61320418],

[0.73268281, 0.45069099, 1.1327083 ],

[0.52385799, 2.30847308, 1.19501328]])

1.7.2.2 随机打乱ndarray数组顺序

(1)随机打乱1维ndarray数组顺序

In [127]

# 生成一维数组
a = np.arange(0, 30)
print('before random shuffle: ', a)
# 打乱一维数组顺序
np.random.shuffle(a)
print('after random shuffle: ', a)

before random shuffle: [ 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]

after random shuffle: [14 3 20 21 9 26 25 1 22 23 0 11 17 10 27 16 6 19 13 15 8 2 28 18

29 7 4 5 12 24]

从输出结果看,所有元素位置都被打乱了。

(2)随机打乱2维ndarray数组顺序

In [128]

# 生成一维数组
a = np.arange(0, 30)
# 将一维数组转化成2维数组
a = a.reshape(10, 3)
print('before random shuffle: \n{}'.format(a))
# 打乱一维数组顺序
np.random.shuffle(a)
print('after random shuffle: \n{}'.format(a))

从输出结果看,只有行的顺序被打乱了,列顺序不变。

1.7.2.3 随机选取元素

In [129]

# 随机选取部分元素
a = np.arange(30)
b = np.random.choice(a, size=5)
b

array([23, 3, 29, 16, 20])

这篇关于《零基础实践深度学习》1.7 附录:NumPy介绍 ndarray的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/708486

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss