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

数据分析三剑客之一:Numpy详解及实战

1 NumPy介绍

NumPy 软件包是Python生态系统中数据分析、机器学习和科学计算的主力军。它极大地简化了向量和矩阵的操作处理。Python的一些主要软件包(如 scikit-learn、SciPy、pandas 和 tensorflow)都以 NumPy 作为其架构的基础部分。除了能对数值数据进行切片(slice)和切块(dice)之外,使用 NumPy 还能为处理和调试上述库中的高级实例带来极大便利,享有数据分析“三剑客之一”的盛名(NumPy、Matplotlib、Pandas)。

1.1 NumPy的主要特点

  • 多维数组:NumPy引入了多维数组对象(称为numpy.ndarray或简称为数组),它允许你在单个数据结构中存储和操作多维数据,如向量、矩阵和张量。

  • 快速的数值运算:NumPy的底层实现是用C语言编写的,因此它能够执行高效的数值计算。它提供了一系列高度优化的数学函数,可用于执行各种数学和统计操作。

  • 强大的索引和切片:NumPy提供了丰富的索引和切片功能,允许你高效地访问和操作数组的元素。

  • 丰富的数学函数库:NumPy包含了大量的数学函数,用于执行各种数值计算,如三角函数、指数函数、对数函数等。NumPy包含了线性代数操作的函数,如矩阵乘法、特征值分解、奇异值分解等,使其成为数值线性代数的强大工具。

  • 互操作性:NumPy与其他常用的科学计算库(如SciPy、pandas和Matplotlib)紧密集成,使得在不同库之间传递数据变得非常容易。

1.2 NumPy数据类型

NumPy支持的数据类型比 Python 内置的类型要多很多,基本上可以和 C 语言的数据类型对应上,其中部分类型对应为 Python 内置的类型。下表列举了常用 NumPy 基本类型。

名称描述
bool_布尔型数据类型(True 或者 False)
int_默认的整数类型(类似于 C 语言中的 long,int32 或 int64)
intc与 C 的 int 类型一样,一般是 int32 或 int 64
intp用于索引的整数类型(类似于 C 的 ssize_t,一般情况下仍然是 int32 或 int64)
int8字节(-128 to 127)
int16整数(-32768 to 32767)
int32整数(-2147483648 to 2147483647)
int64整数(-9223372036854775808 to 9223372036854775807)
uint8无符号整数(0 to 255)
uint16无符号整数(0 to 65535)
uint32无符号整数(0 to 4294967295)
uint64无符号整数(0 to 18446744073709551615)
float_float64 类型的简写
float16半精度浮点数,包括:1 个符号位,5 个指数位,10 个尾数位
float32单精度浮点数,包括:1 个符号位,8 个指数位,23 个尾数位
float64双精度浮点数,包括:1 个符号位,11 个指数位,52 个尾数位
complex_complex128 类型的简写,即 128 位复数
complex64复数,表示双 32 位浮点数(实数部分和虚数部分)
complex128复数,表示双 64 位浮点数(实数部分和虚数部分)

numpy的数值类型实际上是dtype对象的实例,并对应唯一的字符,包括np.bool_,np.int32,np.float32等等。

数据类型对象 (dtype)

数据类型对象(numpy.dtype 类的实例)用来描述与数组对应的内存区域是如何使用,它描述了数据的以下几个方面::

  • 数据的类型(整数,浮点数或者 Python 对象)
  • 数据的大小(例如, 整数使用多少个字节存储)
  • 数据的字节顺序(小端法或大端法)
  • 在结构化类型的情况下,字段的名称、每个字段的数据类型和每个字段所取的内存块的部分
  • 如果数据类型是子数组,那么它的形状和数据类型是什么。

字节顺序是通过对数据类型预先设定“<”或“>”来决定的。

  • “<”意味着小端法(最小值存储在最小的地址,即低位组放在最前面)。
  • “>”意味着大端法(最重要的字节存储在最小的地址,即高位组放在最前面)。

dtype 对象是使用以下语法构造的:

numpy.dtype(object, align, copy)
  • object - 要转换为的数据类型对象
  • align - 如果为 true,填充字段使其类似C的结构体。
  • copy - 复制 dtype 对象 ,如果为false,则是对内置数据类型对象的引用

1.3 ndarray对象

NumPy最重要的一个特点是其N维数组对象ndarray,它是一系列同类型数据的集合,以0下标为开始进行集合中元素的索引。
(1)ndarray对象是用于存放同类型元素的多维数组。
(2)ndarray中的每个元素在内存中都有相同存储大小的区域。
(3)ndarray内部由以下内容组成:

  • 一个指向数据(内存或内存映射文件中的一块数据)的指针。
  • 数据类型或dtype,描述在数组中的固定大小值的格子。
  • 一个表示数组形状(shape)的元组,表示各维度大小的元组。

NumPy的数组中比较重要ndarray对象属性有:

 2 NumPy的使用

2.1 创建数组

我们可以通过传递一个 python 列表并使用 np.array()来创建 NumPy 数组(可以是一维或多为数组):

import numpy as npna1 = np.array([1, 2, 3])
na2 = np.array([[1, 2, 3], [4, 5, 6]])print('na1:', type(na1), na1)
print('na2:', type(na2), na2)

运行结果显示如下:

na1: <class 'numpy.ndarray'> [1 2 3]
na2: <class 'numpy.ndarray'> [[1 2 3][4 5 6]]

通常我们希望NumPy 能初始化数组的值,为此NumPy提供了ones()、zeros() 和 random.random() 等方法。我们只需传递希望 NumPy 生成的元素数量即可:

import numpy as npna3 = np.ones(3)
na4 = np.zeros(3)
na5 = np.random.random(3)
print('na3:', type(na3), na3)
print('na4:', type(na4), na4)
print('na5:', type(na5), na5)

运行结果显示如下:

na3: <class 'numpy.ndarray'> [1. 1. 1.]
na4: <class 'numpy.ndarray'> [0. 0. 0.]
na5: <class 'numpy.ndarray'> [0.69669951 0.86211956 0.37149526]

2.2 数组的算术运算

若要计算两个数组的加法,只需要+号操作,就可以实现对应位置上的数据相加的操作(即每行数据进行相加),这种操作比循环读取数组的方法代码实现更加简洁。

import numpy as npna6 = np.array([[1, 2, 3], [4, 5, 6]])
na7 = np.ones((2, 3))
na8 = na6 + na7
print('na6:', type(na6), na6)
print('na7:', type(na7), na7)
print('na8:', type(na8), na8)

运行结果显示:

na6: <class 'numpy.ndarray'> [[1 2 3][4 5 6]]
na7: <class 'numpy.ndarray'> [[1. 1. 1.][1. 1. 1.]]
na8: <class 'numpy.ndarray'> [[2. 3. 4.][5. 6. 7.]]

减法、乘法和除法等操作与加法一致

import numpy as npna9 = np.array([[1, 2, 3], [4, 5, 6]])
na10 = np.array([[1, 2, 3], [4, 5, 6]])
na11 = na10 - na9
na12 = na10 * na9
na13 = na10 / na9print('na9:', type(na9), na9)
print('na10:', type(na10), na10)
print('na11:', type(na11), na11)
print('na12:', type(na12), na12)
print('na13:', type(na13), na13)

运行结果显示如下:

na9: <class 'numpy.ndarray'> [[1 2 3][4 5 6]]
na10: <class 'numpy.ndarray'> [[1 2 3][4 5 6]]
na11: <class 'numpy.ndarray'> [[0 0 0][0 0 0]]
na12: <class 'numpy.ndarray'> [[ 1  4  9][16 25 36]]
na13: <class 'numpy.ndarray'> [[1. 1. 1.][1. 1. 1.]]

许多情况下,我们希望进行数组和单个数值的操作(也称作向量和标量之间的操作)。NumPy通过数组广播(broadcasting)知道这种操作需要和数组的每个元素相乘。

import numpy as npna14 = np.array([[1, 2, 3], [4, 5, 6]])
na15 = na14 * 3
print('na14:', type(na14), na6)
print('na15:', type(na15), na15)

运行结果显示如下:

na14: <class 'numpy.ndarray'> [[1 2 3][4 5 6]]
na15: <class 'numpy.ndarray'> [[ 3  6  9][12 15 18]]

2.3 数组的切片操作

我们可以像python列表操作那样对NumPy数组进行索引和切片,如下图所示:

import numpy as npna16 = np.array([[1, 2, 3], [4, 5, 6]])
na17 = na16[0]
na18 = na16[:, 0:2]
na19 = na16[:, :1]
na20 = na16[:, 1:]print('na16:', type(na16), na16)
print('na17:', type(na17), na17)
print('na18:', type(na18), na18)
print('na19:', type(na19), na19)
print('na20:', type(na20), na20)

运行结果显示如下:

na15: <class 'numpy.ndarray'> [[ 3  6  9][12 15 18]]
na16: <class 'numpy.ndarray'> [[1 2 3][4 5 6]]
na17: <class 'numpy.ndarray'> [1 2 3]
na18: <class 'numpy.ndarray'> [[1 2][4 5]]
na19: <class 'numpy.ndarray'> [[1][4]]
na20: <class 'numpy.ndarray'> [[2 3][5 6]]

2.4 聚合函数

NumPy的聚合函数可以将数据进行压缩,统计数组中的一些特征值:

import numpy as npna21 = np.array([[1, 2, 3], [4, 5, 6]])
print('na21:', type(na21), na21)
print('na21.max:', na21.max())
print('na21.min:', na21.min())
print('na21.sum:', na21.sum())

运行代码显示结果如下:

na21: <class 'numpy.ndarray'> [[1 2 3][4 5 6]]
na21.max: 6
na21.min: 1
na21.sum: 21

除了min,max和sum等函数,还有mean(均值),prod(数据乘法)计算所有元素的乘积,std(标准差)等等。NumPy能够所有函数应用到任意维度上。

2.5 数组的转置

处理矩阵时经常需要对矩阵进行转置操作,常见的情况如计算两个矩阵的点积。NumPy数组的属性T可用于获取矩阵的转置。

import numpy as npna22 = np.array([[1, 2, 3], [4, 5, 6]])
na23 = na22.T
print('na22:', type(na22), na22)
print('na23:', type(na23), na23)

运行结果显示如下:

na22: <class 'numpy.ndarray'> [[1 2 3][4 5 6]]
na23: <class 'numpy.ndarray'> [[1 4][2 5][3 6]]

2.6 数组的维度变换

在较为复杂的用例中,改变某个矩阵的维度在机器学习应用中很常见,例如模型的输入矩阵形状与数据集不同,可以使用NumPy的reshape()方法。只需将矩阵所需的新维度传入即可。也可以传入-1,NumPy可以根据你的矩阵推断出正确的维度:

import numpy as npna24 = np.array([[1, 2, 3], [4, 5, 6]])
na25 = na24.reshape(-1)
na26 = na24.reshape(3, -1)print('na24:', type(na24), na24)
print('na25:', type(na25), na25)
print('na26:', type(na26), na26)

运行结果显示如下:

na24: <class 'numpy.ndarray'> [[1 2 3][4 5 6]]
na25: <class 'numpy.ndarray'> [1 2 3 4 5 6]
na26: <class 'numpy.ndarray'> [[1 2][3 4][5 6]]

2.7 串联数组

在Numpy中,连接或连接两个数组主要通过以下例程完成:

  • np.concatenate ()
  • np.vstack ()
  • np.hstack ()

hstack()是横向拉伸,vstack()是纵向排列

import numpy as npa = np.array([1, 2, 3])
b = np.array([4, 5, 6])
print('np.concatenate:', np.concatenate([a, b]))
print('np.stack:', np.stack((a, b)))
print('np.hstack:', np.hstack((a, b)))
print('np.vstack:', np.vstack((a, b)))

运行代码显示如下:

np.concatenate: [1 2 3 4 5 6]
np.stack: [[1 2 3][4 5 6]]
np.hstack: [1 2 3 4 5 6]
np.vstack: [[1 2 3][4 5 6]]

2.8 创建数组的副本

为了防止原数据被更改,我们需要使用数组的副本进行修改

import numpy as npn1 = np.array([1, 2, 3, 4, 5, 6])
n2 = n1.copy()
n2[2] = 16print('n1,', n1)
print('n2,', n2)

运行结果显示如下:

n1, [1 2 3 4 5 6]
n2, [ 1  2 16  4  5  6]

当使用了copy函数之后,原先数组的内容没有被改变 

2.9 生成随机数

函数名                                   说明
seed([seed])                          设定随机种子,这样每次生成的随机数会相同
rand(d0,d1,d2.....)                   返回数据在[0,1)之间,具有均匀分布
randn(d0,d1,d2....)                   返回标准正态分布(均值0,方差1)
randint(low[,high,size,dtype])        返回随机整数,包含low,不包含high
choice(a[,size,replace,p])            a是一个数组,从它之间生成随机结果
random([size])                        随机生成[0.0,1.0)之间的小数
shuffle(x)                            把数组x进行随机排列
permutation(x)                        把数组x进行随机排列,或数字的全排列
normal([loc,scale,size])           按照平均值loc和方差scale生成高斯分布的数字
uniform([loc,high,size])              在[loc,high)之间生成均匀分布的数字    

示例代码如下:

from numpy import random# 设定随机数种子
random.seed(134)# 产生均匀分布的随机数,维度是 3*2
rd1 = random.rand(3, 2)# 产生标准正态分布随机数,维度是3*2
rd2 = random.randn(3, 2)# 在[0,1)内产生随机数,维度是3*2
rd3 = random.random((3, 2))# 产生指定区间的随机整数,维度是3*2
rd4 = random.randint(low=2, high=10, size=(3, 2))# 正态分布,loc表示均值,scale表示方差
rd5 = random.normal(loc=0, scale=1, size=(3, 2))# 泊松分布
rd6 = random.poisson(lam=100, size=(3, 2))# 均匀分布
rd7 = random.uniform(low=3, high=10, size=(3, 2))# 产生beta分布
rd8 = random.beta(a=3, b=5, size=(3, 2))# 二项分布(伯努利分布)
rd9 = random.binomial(n=4, p=0.8, size=(3, 2))# 指数分布
rd10 = random.exponential(scale=3, size=(3, 2))# F分布
rd11 = random.f(dfnum=100, dfden=5, size=(3, 2))print('rd1:均匀分布随机数,', type(rd1), rd1)
print('rd2:标准正态分布随机数,', type(rd2), rd2)
print('rd3:[0,1)内随机数,', type(rd3), rd3)
print('rd4:指定区间随机整数,', type(rd4), rd4)
print('rd5:正态分布随机数,', type(rd5), rd5)
print('rd6:泊松分布随机数,', type(rd6), rd6)
print('rd7:均匀分布随机数,', type(rd7), rd7)
print('rd8:beta分布随机数,', type(rd8), rd8)
print('rd9:二项分布随机数,', type(rd9), rd9)
print('rd10:指数分布随机数,', type(rd10), rd10)
print('rd11:F分布随机数,', type(rd11), rd11)

代码运行结果如下:

rd1:均匀分布随机数, <class 'numpy.ndarray'> [[0.81140363 0.44776424][0.62774566 0.88189881][0.66507475 0.88336659]]
rd2:标准正态分布随机数, <class 'numpy.ndarray'> [[ 0.97039702  1.24282664][-0.67460194 -0.84406944][ 0.93530265 -0.61157504]]
rd3:[0,1)内随机数, <class 'numpy.ndarray'> [[0.25060872 0.42907009][0.1313138  0.89065944][0.82592591 0.83688403]]
rd4:指定区间随机整数, <class 'numpy.ndarray'> [[8 5][9 6][2 2]]
rd5:正态分布随机数, <class 'numpy.ndarray'> [[ 1.100513   -0.42039106][-1.10360106  0.02232551][ 0.32110961 -0.36777648]]
rd6:泊松分布随机数, <class 'numpy.ndarray'> [[107 115][115 103][106  96]]
rd7:均匀分布随机数, <class 'numpy.ndarray'> [[9.89957515 7.41625103][8.93349957 8.06628742][5.32215763 9.38106301]]
rd8:beta分布随机数, <class 'numpy.ndarray'> [[0.2429263  0.27533795][0.41979653 0.35869193][0.28791419 0.58321106]]
rd9:二项分布随机数, <class 'numpy.ndarray'> [[3 4][3 3][2 3]]
rd10:指数分布随机数, <class 'numpy.ndarray'> [[ 4.0339984  17.68071959][ 4.47291717  0.35065901][ 1.85350233  4.68708558]]
rd11:F分布随机数, <class 'numpy.ndarray'> [[1.8011784  2.64674957][0.84790891 3.0107673 ][1.17835139 0.80522586]]

2.10 排序、条件筛选函数

NumPy 提供了多种排序的方法。 这些排序函数实现不同的排序算法,每个排序算法的特征在于执行速度,最坏情况性能,所需的工作空间和算法的稳定性。 下表显示了三种排序算法的比较。

种类速度最坏情况工作空间稳定性
'quicksort'(快速排序)1O(n^2)0
'mergesort'(归并排序)2O(n*log(n))~n/2
'heapsort'(堆排序)3O(n*log(n))0

numpy.sort() 函数返回输入数组的排序副本。函数格式如下:

numpy.sort(a, axis, kind, order)

参数说明:

  • a: 要排序的数组
  • axis: 沿着它排序数组的轴,如果没有数组会被展开,沿着最后的轴排序, axis=0 按列排序,axis=1 按行排序
  • kind: 默认为'quicksort'(快速排序)
  • order: 如果数组包含字段,则是要排序的字段

 示例代码如下:

import numpy as npnp1 = np.array([[1, 2, 3], [4, 5, 6]])
print('np1,', np.sort(a))
print('np1 sort,', np.sort(a))
print('np1 sort(a, axis=0),', np.sort(a, axis=0))
dt = np.dtype([('name', 'S10'), ('age', int)])
np2 = np.array([("raju", 21), ("anil", 25), ("ravi", 17), ("amar", 27)], dtype=dt)
print('np2,', np2)
print('np2 sort,', np.sort(np2, order='name'))

 运行结果显示如下:

np1, [1 2 3]
np1 sort, [1 2 3]
np1 sort(a, axis=0), [1 2 3]
np2, [(b'raju', 21) (b'anil', 25) (b'ravi', 17) (b'amar', 27)]
np2 sort, [(b'amar', 27) (b'anil', 25) (b'raju', 21) (b'ravi', 17)]

numpy.argsort() 函数返回的是数组值从小到大的索引值。示例代码如下:

import numpy as npnp3 = np.array([3, 1, 2])
idx = np.argsort(np3)
print('np3,', np3)
print('np.argsort,', idx)
print('以排序后的顺序重构原数组:', np3[idx])

 运行结果显示:

np3, [3 1 2]
np.argsort, [1 2 0]
以排序后的顺序重构原数组: [1 2 3]

numpy.lexsort() 用于对多个序列进行排序。把它想象成对电子表格进行排序,每一列代表一个序列,排序时优先照顾靠后的列。

这里举一个应用场景:小升初考试,重点班录取学生按照总成绩录取。在总成绩相同时,数学成绩高的优先录取,在总成绩和数学成绩都相同时,按照英语成绩录取。这里,总成绩排在电子表格的最后一列,数学成绩在倒数第二列,英语成绩在倒数第三列。

import numpy as npnm = ('raju', 'anil', 'ravi', 'amar')
dv = ('f.y.', 's.y.', 's.y.', 'f.y.')
ind = np.lexsort((dv, nm))
print('lexsort处理后:', ind)
print('使用这个索引来获取排序后的数据:', [nm[i] + ", " + dv[i] for i in ind])

运行结果显示如下:

以排序后的顺序重构原数组: [1 2 3]
lexsort处理后: [3 1 0 2]
使用这个索引来获取排序后的数据: ['amar, f.y.', 'anil, s.y.', 'raju, f.y.', 'ravi, s.y.']

numpy.where() 函数返回输入数组中满足给定条件的元素的索引。

import numpy as npnp4 = np.arange(9.).reshape(3,  3)
print('np4:', np4)
print('大于3的元素的索引:')
np5 = np.where(np4 > 3)
print(np5)
print('使用这些索引来获取满足条件的元素:')
print(np4[np5])

 运行结果显示如下:

np4: [[0. 1. 2.][3. 4. 5.][6. 7. 8.]]
大于3的元素的索引:
(array([1, 1, 2, 2, 2], dtype=int64), array([1, 2, 0, 1, 2], dtype=int64))
使用这些索引来获取满足条件的元素:
[4. 5. 6. 7. 8.]

2.11 公式应用

NumPy的关键用例是实现适用于矩阵和向量的数学公式。这也Python中常用NumPy的原因。例如,均方误差是监督机器学习模型处理回归问题的核心:

在NumPy中可以很容易地实现均方误差:

图片

这样做的好处是,numpy无需考虑predictions与labels具体包含的值,代码示例如下:

import numpy as nppredictions = np.array([1, 1, 1])
lables = np.array([1, 2, 3])
error = (1/3) * np.sum(np.square(predictions - lables))print('error:', error)

运行结果显示如下:

error: 1.6666666666666665

2.12 表和电子表格

电子表格或数据表都是二维矩阵。电子表格中的每个工作表都可以是自己的变量。python中类似的结构是pandas数据帧(dataframe),它实际上使用NumPy来构建的。

2.13 音频和时间序列

音频文件是一维样本数组。每个样本都是代表一小段音频信号的数字。CD质量的音频每秒可能有44,100个采样样本,每个样本是一个-65535到65536之间的整数。这意味着如果你有一个10秒的CD质量的WAVE文件,你可以将它加载到长度为10 * 44,100 = 441,000个样本的NumPy数组中。想要提取音频的第一秒?只需将文件加载到我们称之为audio的NumPy数组中,然后截取audio[:44100]。

以下是一段音频文件:

时间序列数据也是如此(例如,股票价格随时间变化的序列)。

2.14 图像数据

图像是大小为(高度×宽度)的像素矩阵。如果图像是黑白图像(也称为灰度图像),则每个像素可以由单个数字表示(通常在0(黑色)和255(白色)之间)。如果对图像做处理,裁剪图像的左上角10 x 10大小的一块像素区域,用NumPy中的image[:10,:10]就可以实现。

这是一个图像文件的片段:

如果图像是彩色的,则每个像素由三个数字表示 :红色,绿色和蓝色。在这种情况下,我们需要第三维(因为每个单元格只能包含一个数字)。因此彩色图像由尺寸为(高x宽x 3)的ndarray表示。

2.15 语言文本数据

如果我们处理文本,情况就会有所不同。用数字表示文本需要两个步骤,构建词汇表(模型知道的所有唯一单词的清单)和嵌入(embedding)。让我们看看用数字表示这个(翻译的)古语引用的步骤:“Have the bards who preceded me left any theme unsung?”

模型需要先训练大量文本才能用数字表示这位战场诗人的诗句。我们可以让模型处理一个小数据集,并使用这个数据集来构建一个词汇表(71,290个单词):

图片

然后可以将句子划分成一系列“词”token(基于通用规则的单词或单词部分):

图片

然后我们用词汇表中的id替换每个单词:

图片

这些ID仍然不能为模型提供有价值的信息。因此,在将一系列单词送入模型之前,需要使用嵌入(embedding)来替换token/单词(在本例子中使用50维度的word2vec嵌入):

图片

你可以看到此NumPy数组的维度为[embedding_dimension x sequence_length]。

在实践中,这些数值不一定是这样的,但我以这种方式呈现它是为了视觉上的一致。出于性能原因,深度学习模型倾向于保留批数据大小的第一维(因为如果并行训练多个示例,则可以更快地训练模型)。很明显,这里非常适合使用reshape()。例如,像BERT这样的模型会期望其输入矩阵的形状为:[batch_size,sequence_length,embedding_size]。

相关文章:

数据分析三剑客之一:Numpy详解及实战

1 NumPy介绍 NumPy 软件包是Python生态系统中数据分析、机器学习和科学计算的主力军。它极大地简化了向量和矩阵的操作处理。Python的一些主要软件包&#xff08;如 scikit-learn、SciPy、pandas 和 tensorflow&#xff09;都以 NumPy 作为其架构的基础部分。除了能对数值数据…...

【C语言】函数的定义、传参与调用(二)

&#x1f497;个人主页&#x1f497; ⭐个人专栏——C语言初步学习⭐ &#x1f4ab;点击关注&#x1f929;一起学习C语言&#x1f4af;&#x1f4ab; 目录 导读&#xff1a; 1. 函数的嵌套调用 1.1 什么是嵌套调用 1.2 基础实现 1.3 调用流程解析 2. 函数的链式访问 2.1 …...

Sentinel安装

Sentinel 微服务保护的技术有很多&#xff0c;但在目前国内使用较多的还是Sentinel&#xff0c;所以接下来我们学习Sentinel的使用。 1.介绍和安装 Sentinel是阿里巴巴开源的一款服务保护框架&#xff0c;目前已经加入SpringCloudAlibaba中。官方网站&#xff1a; 首页 | Se…...

【JVM】并发可达性分析-三色标记算法

欢迎访问&#x1f44b;zjyun.cc 可达性分析 为了验证堆中的对象是否为可回收对象&#xff08;Garbage&#xff09;标记上的对象&#xff0c;即是存活的对象&#xff0c;不会被垃圾回收器回收&#xff0c;没有标记的对象会被垃圾回收器回收&#xff0c;在标记的过程中需要stop…...

黑豹程序员-架构师学习路线图-百科:Git/Gitee(版本控制)

文章目录 1、什么是版本控制2、特点3、发展历史4、SVN和Git比较5、Git6、GitHub7、Gitee&#xff08;国产&#xff09;8、Git的基础命令 1、什么是版本控制 版本控制系统&#xff08; Version Control &#xff09;版本控制是一种管理和跟踪软件开发过程中的代码变化的系统。它…...

《Jetpack Compose从入门到实战》第一章 全新的 Android UI 框架

书籍源码 Compose官方文档 《Jetpack Compose从入门到实战》第一章 全新的 Android UI 框架 《Jetpack Compose从入门到实战》 第二章 了解常用UI组件 《Jetpack Compose从入门到实战》第三章 定制 UI 视图 《Jetpack Compose从入门到实战》第八章 Compose页面 导航 《Jet…...

基于Spring Boot的中小型医院网站的设计与实现

目录 前言 一、技术栈 二、系统功能介绍 前台首页界面 用户登录界面 用户注册界面 门诊信息详情界面 预约挂号界面 药品详情界面 体检报告界面 管理员登录界面 用户管理界面 医师管理界面 科室类型管理界面 门诊信息管理界面 药库信息管理界面 预约挂号管理界面…...

uniapp iOS离线打包——如何创建App并提交版本审核?

uniapp 如何创建App&#xff0c;并提交版本审核&#xff1f; 文章目录 uniapp 如何创建App&#xff0c;并提交版本审核&#xff1f;登录 appstoreconnect创建AppiOS 预览和截屏应用功能描述技术支持App 审核信息 App 信息内容版权年龄分级 价格与销售范围App 隐私提交审核 登录…...

论文笔记:Contrastive Trajectory Similarity Learning withDual-Feature Attention

ICDE 2023 1 intro 1.1 背景 轨迹相似性&#xff0c;可以分为两类 启发式度量 根据手工制定的规则&#xff0c;找到两条轨迹之间基于点的匹配学习式度量 通过计算轨迹嵌入之间的距离来预测相似性值上述两种度量的挑战&#xff1a; 无效性&#xff1a; 具有不同采样率或含有噪…...

整数和字符串比较的坑

结果竟然是相同&#xff0c;惊呆了吧&#xff1f; $num1 2023快放假了; $num2 2023;if ($num1 $num2) {echo 相同; } else {echo 不相同; }num2改成字符串类型&#xff0c;结果&#xff1a;不相同&#xff0c;又不懵了吧&#xff1f; $num1 2023快放假了; $num2 2023;if…...

LeetCode 面试题 08.04. 幂集

文章目录 一、题目二、C# 题解 一、题目 幂集。编写一种方法&#xff0c;返回某集合的所有子集。集合中不包含重复的元素。 说明&#xff1a; 解集不能包含重复的子集。 示例: 输入&#xff1a; nums [1,2,3] 输出&#xff1a; [ [3], [1], [2], [1,2,3], [1,3], [2,3], [1…...

【m_listCtrl !=NULL有多个运算符与操作数匹配】2023/9/21 上午11:03:44

2023/9/21 上午11:03:44 m_listCtrl !=NULL有多个运算符与操作数匹配 2023/9/21 上午11:04:00 如果您在编译或运行代码时遇到"M_listCtrl != NULL有多个运算符与操作数匹配"的错误提示,这通常是由于以下几个原因之一: 错误使用运算符:在条件判断语句中,应该使…...

Logrus 集成 color 库实现自定义日志颜色输出字符原理

问题背景 下列代码实现了使用 Logurs 日志框架输出日志时根据级别不同&#xff0c;使用对应的自定义颜色进行输出。那么思考下代码的逻辑是怎么实现的呢&#xff1f; 效果如下&#xff1a; 代码如下&#xff1a; import ("fmt""github.com/sirupsen/logrus&q…...

【Java-LangChain:使用 ChatGPT API 搭建系统-2】语言模型,提问范式与 Token

第二章 语言模型&#xff0c;提问范式与 Token 在本章中&#xff0c;我们将和您分享大型语言模型&#xff08;LLM&#xff09;的工作原理、训练方式以及分词器&#xff08;tokenizer&#xff09;等细节对 LLM 输出的影响。我们还将介绍 LLM 的提问范式&#xff08;chat format…...

想要精通算法和SQL的成长之路 - 最长连续序列

想要精通算法和SQL的成长之路 - 最长连续序列 前言一. 最长连续序列1.1 并查集数据结构创建1.2 find 查找1.3 union 合并操作1.4 最终代码 前言 想要精通算法和SQL的成长之路 - 系列导航 并查集的运用 一. 最长连续序列 原题链接 这个题目&#xff0c;如何使用并查集是一个小难…...

UG NX二次开发(C#)- 制图(Draft)-工程图框选制图曲线并输出制图曲线的信息

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1、前言2、在UG NX中打开一个装配体模型3、进入工程制图模块,创建工程制图4、在VS中创建一个工程项目5、在Main()中添加选择的代码(UFun)6、在Main()中添加选择的代码(NXOpen)7、框选解决方案…...

1.7.C++项目:仿muduo库实现并发服务器之Poller模块的设计

项目完整在&#xff1a; 文章目录 一、Poller模块&#xff1a;描述符IO事件监控模块二、提供的功能三、实现思想&#xff08;一&#xff09;功能&#xff08;二&#xff09;意义&#xff08;三&#xff09;功能设计 四、封装思想五、代码&#xff08;一&#xff09;框架&#…...

Flutter笔记:build方法、构建上下文BuildContext解析

Flutter笔记 build 方法解析 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/details/133556333 本文主要介绍Flu…...

composer 安装和基本使用

php的包管理软件 如果没有安装php&#xff0c;参考这篇&#xff1a;添加链接描述 1.composer安装 composer官网 需要先安装好php&#xff0c;同时php -v输出有信息 cd /usr/localphp -r "copy(https://install.phpcomposer.com/installer, composer-setup.php);"…...

Ubuntu配置深度学习环境(TensorFlow和PyTorch)

文章目录 一、CUDA安装1.1 安装显卡驱动1.2 CUDA安装1.3 安装cuDNN 二、Anaconda安装三、安装TensorFlow和pyTorch3.1 安装pyTorch3.2 安装TensorFlow2 四、安装pyCharm4.1 pyCharm的安装4.2 关联anaconda的Python解释器 五、VScode配置anaconda的Python虚拟环境 前言&#xff…...

【产品经理】国内企业服务SAAS平台的生存与发展

SaaS在国外发展的比较成熟&#xff0c;甚至已经成为了主流&#xff0c;但在国内这几年才掀起热潮&#xff1b;企业服务SaaS平台在少部分行业发展较快&#xff0c;大部分行业在国内还处于起步、探索阶段&#xff1b;SaaS将如何再国内生存和发展&#xff1f; 在企业服务行业做了五…...

【vue 首屏加载优化】

Vue 首屏加载优化指的是通过一系列的技术手段&#xff0c;尽可能地缩短首屏&#xff08;即页面中可见的部分&#xff09;的加载时间&#xff0c;提高用户体验。 以下是一些常见的 Vue 首屏加载优化技巧&#xff1a; 使用 Vue SSR&#xff08;服务端渲染&#xff09;&#xff1…...

docker--redis容器部署及与SpringBoot整合-I

文章目录 1. 容器化部署docker2. 如何与SpringBoot集成2.1. 引入依赖2.2. 添加配置信息2.3. 测试类2.4. 内置的Spring Beansredis 主流客户端比较redissonlettucejedis参考1. 容器化部署docker 拉取镜像创建数据目录data 及 配置目录conf创建配置文件redis.conf启动redis容器进…...

力扣 -- 518. 零钱兑换 II(完全背包问题)

解题步骤&#xff1a; 参考代码&#xff1a; 未优化代码&#xff1a; class Solution { public:int change(int amount, vector<int>& coins) {int ncoins.size();//多开一行&#xff0c;多开一列vector<vector<int>> dp(n1,vector<int>(amount1…...

一文搞懂UART通信协议

目录 1、UART简介 2、UART特性 3、UART协议帧 3.1、起始位 3.2、数据位 3.3、奇偶校验位 3.4、停止位 4、UART通信步骤 1、UART简介 UART&#xff08;Universal Asynchronous Receiver/Transmitter&#xff0c;通用异步收发器&#xff09;是一种双向、串行、异步的通信…...

【算法|动态规划No.7】leetcode300. 最长递增子序列

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希望…...

LeetCode 54 螺旋矩阵

先贴代码 ​ class Solution {public int[][] generateMatrix(int n) {int left 0;int right n-1;int up 0;int down n-1;int[][] result new int[n][n];int number 0;while(left < right && up < down) {for(int ileft;i<right;i) {number;result[up]…...

OpenCV 概念、整体架构、各模块主要功能

文章目录 1. OpenCV 概念2 OpenCV主要模块3 各模块 详细介绍3.1 calib3d 标定3.2 core 核心功能模块3.4 features2d 二维特征3.5 flann 快速近似近邻算法库3.7 highgui 高级图形用户界面3.9 imgproc 图像处理模块3.10 ml 机器学习模块3.11 objdetect 目标检测模块3.12 photo 数…...

组合数与莫队——组合数前缀和

用莫队求组合数是一种常见套路 莫队求 S ( n , m ) ∑ i 0 m ( n i ) S(n,m)\sum_{i0}^m\binom n i S(n,m)∑i0m​(in​) S ( n , m 1 ) S(n,m1) S(n,m1) 直接做个差&#xff0c;然后就相当于加上 ( n i 1 ) \binom n {i1} (i1n​) 求 S ( n 1 , m ) S(n1,m) S(n1,m)…...

stm32之雨滴传感器使用记录

一、简介 雨滴传感器、烟雾传感器&#xff08;MQ2&#xff09;、轨迹传感器、干黄管等的原理都类似&#xff0c;都是将检测到的信号通过LM393进行处理之后再输出&#xff0c;可以输出数字信号DO&#xff08;0和1&#xff09;和模拟信号A0。 雨滴传感器在正常情况下是AO输出的是…...

网站建设企业所得税/成都网站制作费用

服务器vps分销 内容精选换一换oVirt Engine是运行在基于JBoss的Java应用程序。该服务与主机上的VDSM进行通信&#xff0c;以部署、启动、停止、迁移和监控VM&#xff0c;并且还可以通过模板在存储上创建新的镜像。oVirt Engine以可扩展性、安全性、高性能为基础的架构技术&…...

做家务的男人们在哪个网站播出/河北seo技术交流

SQL分组获取随机记录 2017-12-30 08:59:32 一木剑 阅读数 1038更多 分类专栏&#xff1a; SQL 版权声明&#xff1a;本文为博主原创文章&#xff0c;遵循 CC 4.0 BY-SA 版权协议&#xff0c;转载请附上原文出处链接和本声明。 本文链接&#xff1a;https://blog.csdn.net/q…...

网站增值业务/网络推广网站公司

2019独角兽企业重金招聘Python工程师标准>>> 1、数据挖掘思维导图 思维导图为&#xff1a;Dr. Saed Sayad总结的An Introduction to Data Mining 个人更喜欢的分类方式为&#xff1a;1、分类与预测2、关联3、聚类4、异常检测 2、信用评分中的常见算法 信用评分中主要…...

市场来说网站建设销售发展怎么样/seo门户网站优化

我们先来看一下&#xff0c;通常一个标准的钱包应用是什么组成。钱包之于区块链应用程序来说&#xff0c;是一个前端工具&#xff0c;其作用主要是提供给用户一个交互操作的应用&#xff0c;以便于用户可以通过钱包来进行密钥管理、转账交易、余额查询、 合约部署等一系列操作。…...

网站的后台怎么做调查问卷/中山口碑seo推广

鉴于有些朋友会遇到Allegro17.2在allegro网标导入后&#xff0c;不能与原理图同步的情况&#xff0c;我们电子布局网在这里给出相关解决办法&#xff0c;希望对各位小伙伴有所帮助。 一、首先打开orcad cis&#xff0c;单击菜单栏 “Options”&#xff0c;在弹出的下拉菜单中单…...

学校网站的建设费用/百度开户代理

许多外贸公司在选择邮箱时&#xff0c;单次群发量和邮箱容量都是客户选择邮箱品牌的必要条件。小编了解到一些做外贸的公司是需要跟海外的客户发邮件业务往来的&#xff0c;所以&#xff0c;他们需要单次群发量非常高&#xff0c;目前小编了解到&#xff0c;还有一些外贸公司的…...