Numpy入门看这一篇就够了【史上入门最简单,开袋即食】

news2024/11/18 6:40:30

一边学习一边分享,好记性不如烂笔头

目录

一边学习一边分享,好记性不如烂笔头

NumPy问题思考:

numpy是什么?

为什么要学习numpy?

numpy是怎么组成的?特点是什么?

numpy的应用场景有哪些?

NumPy介绍:

Tensor概念:

1、ndarray数组

1.1、为什么引入ndarray数组

1.2、创建ndarray数组

1.3、查看ndarray数组的属性

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

1.5、ndarray数组的基本运算

1.6、ndarray数组的索引和切片

1.6.1、一维ndarray数组的索引和切片

2、随机数np.random

2.1、创建随机ndarray数组

2.2、随机打乱ndarray数组顺序

2.3、随机选取元素

3、NumPy保存和导入文件

3.1、文件读写

3.2、文件保存

4、应用举例

4.1、图像翻转和裁剪

4.1.1、库安装:

4.1.2、简单读入:

4.1.3、在pychram中查看原始图片【注意要弄一个窗口,控制台无法直接显示】:

4.1.4、图像翻转【效果用代码跑一遍】:

4.1.5、水平翻转【效果用代码跑一遍】:

4.1.6、水平和垂直都翻转【效果用代码跑一遍】:

4.1.7、保存图片【效果用代码跑一遍】:

4.1.8、裁剪图片【效果用代码跑一遍】:

4.1.9、调整亮度


NumPy问题思考:

numpy是什么?

    1、NumPy是Python科学计算中非常重要的基础库之一,能更好地应用于数据处理、科学计算和机器学习等领域;
    2、NumPy是一个提供了多维数组对象和各种数组操作函数的库
    3、NumPy 将python提供的模块中列表和元组对对象进行了封装,并且加入了很多便于使用数组的方法
    4、学习完NumPy后建议学习pandas,pandas是进一步对NumPy的封装

为什么要学习numpy?

    1、大大提升了python中数据运算的速度
    2、更重要的是NumPy将问题向量化、并行化的思路,在SIMD、CUDA、Shader编程、深度学习的时候都会用到
    3、应用场景多都会用到该库
    4、是科学计算中非常重要的一个工具,适用于处理多维数组和矩阵,尤其在机器学习和数据科学领域广泛应用
    5、在科学计算和机器学习领域,NumPy是一个必不可少的工具,它可以用于处理数据、训练模型和测试模型等方面,并且支持多种常用算法和工具,例如线性回归、逻辑回归、聚类、降维等。

numpy是怎么组成的?特点是什么?

    1、底层是C语言编写的多维数组库,所以运行速度更快,提高了数据科学家和研究人员的工作效率。
    2、提供了高效地读取、创建、预处理和计算多维数组的方法。

numpy的应用场景有哪些?

    1、数据处理和分析:轻松实现数据的读取、处理、转换和整理
    2、科学计算:成为统计分析、概率论、线性代数、图像处理和信号处理等领域的重要工具
    3、机器学习和人工智能:可以实现各种机器学习算法,比如回归,分类和聚类等。
    4、计算机视觉:如图像重构,特征提取,图像分割等。

NumPy介绍:

NumPy(Numerical Python的简称)是高性能科学计算和数据分析的基础包;

构建神经网络模型时,通常会使用NumPy实现数据预处理和一些模型指标的计算,Tensor数据可以很方便的和ndarray数据进行转换;

NumPy具有如下功能:

  • ndarray数组:一个具有矢量算术运算符复杂广播能力多维数组,具有快速且节省空间的特点;

  • 对整组数据进行快速运算的标准数学函数(无需编写循环);

  • 线性代数、随机数生成以及傅里叶变换功能;

  • 读写磁盘数据、操作内存映射文件;

Tensor概念:

很多学习框架都是使用Tensor来表示数据,在神经网络中传递的数据均为Tensor。

可以理解成多维数组,可以具有任意多的维度,不同Tensor可以有不同的数据类型(dtype)和形状(shape)。同一Tensor的所有元素的dtype都相同;

如果你对NumPy熟悉,Tensor是类似于NumPy array的概念,接下来就来学学NumPy,案例;

a = np.asarray([1, 2, 3, 4])
b = np.asarray([22, 3, 44, 66])
c = a + b
print(c)

1、ndarray数组

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

  • 为什么引入ndarray数组

  • 如何创建ndarray数组

  • ndarray数组的基本运算

  • ndarray数组的切片和索引

  • ndarray数组的统计运算

1.1、为什么引入ndarray数组

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

  • ndarray数组中的所有元素的数据类型相同数据地址连续,批量操作数组元素时速度更快。

    list列表元素数据类型可以不同,需要通过寻址方式才能找到下一个元素;

  • ndarray数组支持广播机制,矩阵运算时不需要写for循环;

  • NumPy底层使用c语言编写,内置并行计算功能,运算速度高于python代码。

举几个例子来证明:

———————案例1———————
# python原生的list操作
a = [1, 2, 3, 4, 5]
b = [2, 3, 4, 5, 6]
# 对a列表的元素+1
# a = a + 1  # 这样会报错
for i in range(5):
    a[i] = a[i] + 1
print(a)


# numpy的 a+1 操作方式
b = np.array(b)
b = b + 1
print(b)


———————案例2———————
a = [1, 2, 3, 4, 5]
b = [2, 3, 4, 5, 6]

# 实现c=a+b
# ①传统python的list操作
c = []
for i in range(5):
    c.append(a[i] + b[i])
print(c)

# ②numpy的操作方式
a = np.array(a)
b = np.array(b)
c1 = a + b
print(c1)

总结:通过上面的两个案例可以看出,在不写for循环的情况下,ndarray数组就可以非常方便的完成数学计算,在编写矢量或者矩阵的程序时,可以像编写普通数值一样,使得代码非常简洁;

另外,ndarray数组还提供了广播机制,它会按一定规则自动对数组的维度进行扩展以完成计算,下面的例子:一维数组和二维数组进行相加的操作,ndarray就会自动扩展一维数组的维度,然后再对每个位置的元素分别相加;

案例:

———————案例1———————
# 自动广播机制,1维数组和2维数组相加
a = [[1, 2, 3, 4], [5, 6, 7, 8]]
a = np.array(a)

b = [11, 22, 33, 44]

print(a+b)

———————效果———————
[[12 24 36 48]
 [16 28 40 52]]

注意事项:

  • 广播机制仅适用于形状相似的数组,或者可以通过扩展数组形状使它们变得相似。

  • 两个数组在任一维度上的大小要么相等,要么其中一个数组的大小为 1;

  • 广播机制不会修改原数组的值,而是返回一个新数组。

1.2、创建ndarray数组

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

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

———————案例1———————
# array创建数组
a = [1, 2, 3, 4]
b = np.array(a)
print(b)
c = np.array([5, 6, 7])
print(c)

———————效果———————
[1 2 3 4]
[5 6 7]
  • arange(start,stop,step):创建从start开始到stop结束的数组,左闭右开,步长为step

———————案例1———————
# arange 创建ndarray数组 左闭右开 从1开始,步长为2,一直到10
a = np.arange(1, 10, 2)
print(a)

———————效果———————
[1 3 5 7 9]
  • zeros([]):创建指定长度或者形状的全0数组,括号里面是“,”隔开,数字位数可无限写

———————案例1———————
# zeros([]): 默认是浮点型,所有会有".",
# 括号如果是一个值,就是一维数组,
# 2个值[10,4]:二维,n列,
# 3个值[10,3,4]:创建10组3行4列的三维数组
a = np.zeros([10,3,4])
print(a)

———————效果———————
[[[0. 0. 0. 0.]
  [0. 0. 0. 0.]
  [0. 0. 0. 0.]]
......
  • ones([]):效果和zeros([])一样,只是数值为1,这两个可以用来重置,比如棋盘,初始化;

1.3、查看ndarray数组的属性

ndarray的属性包括shape、dtype、size和ndim等,通过如下代码可以查看数组的属性。

  • shape:数组的形状ndarray.shape,1维(N,),2维(M,N),3维(M,N,K);

  • dtype:数组的数据类型;

  • size:数组中包含的元素个数ndarray.size,其大小等于各个维度的长度的乘积;

  • ndim:数组的维度大小,ndarray.ndim,其大小等于ndarray.shape所包含元素的个数;

———————案例1———————
# 查看ndarray的各个属性
a = np.ones([5])
print(a)
print("a的形状:", a.shape)
print("a的数据类型:", a.dtype)
print("a的元素个数:", a.size)
print("a的维度大小:", a.ndim,"维")

———————效果———————
[1. 1. 1. 1. 1.]
a的形状: (5,)
a的数据类型: float64
a的元素个数: 5
a的维度大小: 1 维
  • 生成随机数

———————案例1———————
# 生成随机数 [0,1)之间生成2个
b = np.random.rand(2)
print(np.random.random(5))
print(b)
print("维度:",b.ndim)

———————效果———————
[0.72329108 0.29206742 0.16020119 0.0181518  0.15668087]
[0.28995899 0.99508755]
维度: 1

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

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

———————案例1———————
# 改变数组的类型和形状
a = np.random.rand(2, 3)
print(a, a.dtype, a.shape)

# 转化数据类型astype 这里是0是因为把小数转没了
b = a.astype(np.int64)
print(b)

# 改变形状 reshape
c = b.reshape([1, 6])
print("c的形状:",c)

———————效果———————
[[0.5554663  0.93000141 0.70539356]
 [0.21511709 0.00952697 0.83371317]] float64 (2, 3)

[[0 0 0]
 [0 0 0]]

c的形状: [[0 0 0 0 0 0]]

改形状注意事项:

  • 个数要对应上,比如在这里不能写成1,5

  • 如果后面参数是-1,前面规定行数,后面能分配成多少列,系统自动分配,可以减少报错,但是前面分配出错导致后面分配不够,那也会报错;比如总数是6个,第一个参数不能写成4;

1.5、ndarray数组的基本运算

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

  • 标量(可以理解成正常的数值,常量)和ndarray数组之间的运算

  • 两个ndarray数组之间的运算

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

# 标量减法
print(2.0 - a)

# 标量乘法
print(2.0 * a)

# 标量除法 取模等
print(2.0 / a)
print(2.0 % a)

# 数组与数组 1组和3组可以,2组和3组就没法,要有一个基础值
a = np.array([[1, 2, 3]])
b = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(a + b)
print(a - b)
print(a * b)
print(a / b)

1.6、ndarray数组的索引和切片

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

ndarray数组的索引和切片的使用方式与python中的list类似,通过[-n,n-1]的下标进行索引,通过内置的slice函数,设置其start,stop和step参数进行切片,从原数组中切割出一个新数组

ndarray数组的索引是一个内容丰富的主题,因为选取数据子集或单个元素的方式有很多,下面从一维数组和多维数组两个维度介绍索引和切片的方法。

1.6.1、一维ndarray数组的索引和切片

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

  • python的列表切片是单独复制一份,重新创建一块内存区域

  • numpy是指向原地址

———————案例1———————
# numpy一位数组的索引和切片使用
a = np.array([1, 2, 3, 4])
a[1] = 10
print("a数组的样子:", a)

b = a[0:2]
b[0] = 10
print("更改后a数组的样子:", a)
print("b数组的样子:", b)



———————效果———————
a数组的样子: [ 1 10  3  4]
更改后a数组的样子: [10 10  3  4]
b数组的样子: [10 10]
———————案例1———————
# numpy二维数组的索引和切片使用
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print("单个索引:", a[0])
print("两个索引-写法1:", a[0][1])
print("两个索引-写法2:", a[0, 1])
print("————————————切片用法")
b = a[0:2]
b[0, 1] = 10
print(b)
print(a)


———————效果———————
单个索引: [1 2 3]
两个索引-写法1: 2
两个索引-写法2: 2
—————切片用法
[[ 1 10  3]
 [ 4  5  6]]
[[ 1 10  3]
 [ 4  5  6]
 [ 7  8  9]]

综上,我们会发现切片的数据更改后,原数据都改了,这就是因为地址引用,都是指向的原来的数据,那么我怎么在numpy里面解决这种问题呢?

解决办法:通过copy给新数组创建不同的内存空间

———————案例1———————
# numpy二维数组的索引和切片使用
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print("单个索引:", a[0])
print("两个索引-写法1:", a[0][1])
print("两个索引-写法2:", a[0, 1])
print("————————————切片用法")
b = a[0:2]
b=np.copy(b)
b[0, 1] = 10
print(b)
print(a)

———————效果———————
单个索引: [1 2 3]
两个索引-写法1: 2
两个索引-写法2: 2
————————————切片用法
[[ 1 10  3]
 [ 4  5  6]]
[[1 2 3]
 [4 5 6]
 [7 8 9]]

2、随机数np.random

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

2.1、创建随机ndarray数组

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

  • 设置随机种子

———————案例1———————
# 设置随机种子的随机数
# 相同的种子值时,多次生成的随机数序列将完全相同,所以一直设置为1出来的随机数都是相同的
np.random.seed(1)
a = np.random.rand(3, 3)
print(a)

———————效果———————
[[4.17022005e-01 7.20324493e-01 1.14374817e-04]
 [3.02332573e-01 1.46755891e-01 9.23385948e-02]
 [1.86260211e-01 3.45560727e-01 3.96767474e-01]]
  • 均匀分布,uniform可以指定范围

———————案例1———————
# 生成均匀分布随机数,随机数取值范围在[0,1)之间,每次不一样
a=np.random.rand(3,3)
print(a)

# 生成均匀分布随机数,指定随机数取值范围和数据形状,uniform方法  low=最小, high=最大
a = np.random.uniform(-1.0, 2.0, size=(2, 2))
print(a)


———————效果———————
[[0.29134465 0.22175308 0.86045294]
 [0.35354551 0.48047924 0.64565728]
 [0.00449983 0.64313651 0.37337913]]
  • 正态分布

# 正态分布 生成标准正态分布(均值为0,方差为1)随机数,random   2就是正态分布模式
np.random.seed(2)
# a = np.random.randn(3, 3)
aa = np.random.normal(1.0, 2.0, size=(3, 3))
print(aa)

2.2、随机打乱ndarray数组顺序

随机打乱一维ndarray数组顺序,发现所有元素位置都被打乱了,代码如下:

———————案例1———————
# 打乱一维数组,先生成
a = np.arange(30)
print("打乱前数组为:", a)
np.random.shuffle(a)
print("打乱后:", a)

———————效果———————
打乱前数组为: [ 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]
打乱后: [21 16 17 20 19  2 14 12 15 26  3  8 22  7 10  5 25 18  1 29 27  4 28  6
  9 24 11  0 23 13]

二维数组打乱[只有行乱,列不乱],代码如下:

———————案例1———————
# 打乱二维数组
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [11, 12, 13], [14, 15, 16], [17, 18, 19]])
print("打乱前数组为:", a)
np.random.shuffle(a)
print("打乱后:", a)

———————效果———————
打乱前数组为: [[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [11 12 13]
 [14 15 16]
 [17 18 19]]
打乱后: [[ 7  8  9]
 [11 12 13]
 [ 4  5  6]
 [17 18 19]
 [ 1  2  3]
 [14 15 16]]

Process finished with exit code 0

2.3、随机选取元素

在一个已有的数组中随机选取指定个数的元素组成新数组,上代码:

———————案例1———————
# 随机选取元素
a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
b = np.random.choice(a, 6)
print(b)
———————效果———————
[ 9  1  2  2 10  8]

3、NumPy保存和导入文件

3.1、文件读写

fromfile函数可以从文件读取数据文档,比如.txt或者.data

1、在项目中创建test.txt文件
2、复制一些数据进去,这个可以用a = np.random.randn(20)生成正态分布的数据
3、读取的代码如下:
b = np.fromfile('test.txt', sep=' ')
print(b)
———————效果———————
[ 0.71487971 -1.2266247   0.21812245  2.02429348 -0.61132262  1.21231402
  0.57125962 -0.01415773  1.57852762 -0.3208648  -2.25181538 -0.35990666
  1.66586577 -0.88487449 -1.07157014 -0.6817527   0.11183847  0.28539159
 -0.90093036  0.5402392 ]

3.2、文件保存

NumPy提供了save和load接口,直接将数组保存成文件(.npy格式),或者从.npy格式文件读取数组;

———————案例1———————
# 文件保存
# 创建一个二维数组
a = np.random.rand(3, 3)
print("生成的数据为:", a)
np.save('a.npy', a)

b = np.load('./a.npy')
print("从磁盘读取的数据为:", b)

———————效果———————
生成的数据为: [[0.98094485 0.99442615 0.86263148]
 [0.75966441 0.95502318 0.33871343]
 [0.27829987 0.56337243 0.38992223]]
从磁盘读取的数据为: [[0.98094485 0.99442615 0.86263148]
 [0.75966441 0.95502318 0.33871343]
 [0.27829987 0.56337243 0.38992223]]

4、应用举例

NumPy既然是可以操作数组,那么最典型的就是处理计算机视觉相关的图片领域了,图片是由一个一个点组成的;

4.1、图像翻转和裁剪

图像是由像素点构成的矩阵,其数值可以用ndarray来表示。将上述介绍的操作用在图像数据对应的ndarray上,就能很轻松的实现图片的翻转、裁剪和亮度调整。

在这里,图片文件是可以提供的,但是还需要一个新库matplotlib;

Matplotlib 是一种用于数据可视化的 Python 库,可以用于绘制各种类型的图形

4.1.1、库安装:

//pip安装
pip install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple   

//导入库
import matplotlib.pyplot as plt
from PIL import Image

4.1.2、简单读入:

———————案例1———————
# 项目展示
# 图片导入
image = Image.open('./img.jpg')
image = np.array(image)
# 查看图片的形状, (249, 252, 3) H是高,W是宽,3是通道,jpg有3个,png有个a透明通道
print("图片的形状", image.shape)

———————效果———————
图片的形状 (249, 252, 3)

4.1.3、在pychram中查看原始图片【注意要弄一个窗口,控制台无法直接显示】:

# 指定要显示的图片
plt.imshow(image)
# 建立一个窗口,让图片显示出来
plt.show()

4.1.4、图像翻转【效果用代码跑一遍】:

# 垂直方向翻转,思维步骤:
# 1、使用数组切片的方式完成
# 2、相当于将图片最后一行挪到第一行...一直切换
# 3、对于行来说,使用::-1来表示,从开始到结尾,然后反过来
# 4、对于列来说和RGB通道,使用:表示该维度不改变即可
image = Image.open('./img.jpg')
image = np.array(image)
image2 = image[::-1, :, :]
# 输出更改后的图片
plt.imshow(image2)
plt.show()

4.1.5、水平翻转【效果用代码跑一遍】:

# 水平方向翻转,思维步骤
# 改列的顺序
image = Image.open('./img.jpg')
image = np.array(image)
image3 = image[:, ::-1, :]
# 输出
plt.imshow(image3)
plt.show()

4.1.6、水平和垂直都翻转【效果用代码跑一遍】:

# 都反转
image = Image.open('./img.jpg')
image = np.array(image)
image3 = image[::-1, ::-1, :]
plt.imshow(image3)
plt.show()

4.1.7、保存图片【效果用代码跑一遍】:

# 都反转
image = Image.open('./img.jpg')
image = np.array(image)
image3 = image[:, :, ::-1]
plt.imshow(image3)
plt.show()
# 保存图片
img=Image.fromarray(image3)
img.save("./11.jpg")

4.1.8、裁剪图片【效果用代码跑一遍】:

# 高度、宽度裁剪,注意要找到起点和终点
# 获取到高和宽
image = Image.open('./img.jpg')
image = np.array(image)
print(image.shape)
H = image.shape[0]
W = image.shape[1]
# 高度裁剪,1/2,这里需要两个斜杠才是除法,单根不算
H1 = H // 2
W1=W//2
image4 = image[H1:H,W1:W, :]
plt.imshow(image4)
plt.show()

4.1.9、调整亮度

# 调整亮度
image = Image.open('./img.jpg')
image = np.array(image)
image = image * 1.5
# 要把类型转换一下,不然数值处理不好
plt.imshow(image.astype('uint8'))
plt.show()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/570093.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

css定位模式

1. 为什么需要定位&#xff1f; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"…

自动化专业求职方向与前景分析(合集)

自动化专业求职方向与前景分析 自动化专业求职方向 自动化专业是近几年高校教育改革中几个控制类专业合并后形成的宽口径专业&#xff0c;其实自动化就是搞控制的&#xff0c;用老师的话说就是控制一切可以控制的物理量&#xff0c;还说学自动化的人都要有控制的欲望。所谓控制…

Augmented Language Models(增强语言模型)

Augmented Language Models: A Survey 先上地址&#xff1a;https://arxiv.org/pdf/2302.07842.pdf 概率论难以支撑通用人工智能技术的诞生。—— Yann LeCun LLMs取得的巨大进展不再多说&#xff0c;它目前被诟病最多的问题是其会提供非事实但看似可信答案&#xff0c;即幻觉…

数组排序——从荷兰国旗问题到快速排序

本文首先将会介绍荷兰国旗问题&#xff0c;再讲述如何从该问题过渡到快速排序。 荷兰国旗问题 荷兰国旗问题&#xff08;Dutch National Flag Problem&#xff09;是由荷兰计算机科学家Edsger Dijkstra所提出&#xff0c;该问题的描述如下&#xff1a; 给定n个红、白、蓝三种颜…

JNDI学习笔记

最近在研究JNDI注入漏洞&#xff0c;就先浅浅的学习以下JNDI相关知识。 JNDI对各种目录服务的实现进行抽象和统一化。 在 Java 应用中除了以常规方式使用名称服务(比如使用 DNS 解析域名)&#xff0c;另一个常见的用法是使用目录服务作为对象存储的系统&#xff0c;即用目录服务…

SpringBoot --- 基础篇

一、快速上手SpringBoot 1.1、概述 SpringBoot开发团队认为原始的Spring程序初始搭建的时候可能有些繁琐&#xff0c;这个过程是可以简化的&#xff0c;那原始的Spring程序初始搭建过程都包含哪些东西了呢&#xff1f;为什么觉得繁琐呢&#xff1f;最基本的Spring程序至少有一…

大数据:VMware | Ubuntu | Hadoop | Spark | VMwaretools | Python 安装配置总结

一.环境概述 Linux发行版&#xff1a;Ubuntu虚拟机应用&#xff1a;VMware Workstation ProHadoop版本&#xff1a;3.1.3|伪分布式集群JDK版本&#xff1a;JDK1.8.0_162Spark版本:2.4.0Scala版本:2.12.8Python版本:3.6.8 | 3.7.16 二.Ubuntu 2.1 光盘文件 首先进入链接Down…

因为AI,我被裁了;MJ设计海报全流程;独立开发者每周收入2.3K美元;MJ常用参数超详细介绍 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f916; 受 AI 影响&#xff0c;这 8 家公司开始裁员…… 为了搞清楚 AI 最近在影响哪些行业、哪些职业&#xff0c;作者花了三天事件找到了八…

基于SSM的网络在线考试系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 前言…

《Java并发编程实战》课程笔记(二)

可见性、原子性和有序性问题&#xff1a;并发编程 Bug 的源头 源头之一&#xff1a;缓存导致的可见性问题 在单核时代&#xff0c;所有的线程都是在一颗 CPU 上执行&#xff0c;CPU 缓存与内存的数据一致性容易解决。 因为所有线程都是操作同一个 CPU 的缓存&#xff0c;一个…

《面试1v1》ThreadLocal

我是 javapub&#xff0c;一名 Markdown 程序员从&#x1f468;‍&#x1f4bb;&#xff0c;八股文种子选手。 面试官&#xff1a; 你好&#xff0c;请问你对 ThreadLocal 有了解吗&#xff1f; 候选人&#xff1a; 您好&#xff0c;我知道 ThreadLocal 是一个 Java 中的类&a…

【坐标变换】坐标系坐标变换简单推导--未完待续

如图所示&#xff0c;假设已知坐标系 ( X , Y ) (X,Y) (X,Y)&#xff0c;旋转后的坐标系为 ( X ′ , Y ′ ) (X,Y) (X′,Y′)&#xff0c;旋转角度为 θ \theta θ&#xff0c;假设点p在 ( X , Y ) (X,Y) (X,Y)坐标系下为 ( x , y ) (x,y) (x,y)&#xff0c;坐标在旋转后的坐标…

速来!谷歌师兄的LeetCode刷题笔记开源了!

有小伙伴私聊我说刚开始刷LeetCode的时候&#xff0c;感到很吃力&#xff0c;刷题效率很低。我以前刷题的时候也遇到这个问题&#xff0c;直到后来看到这个谷歌师兄总结的刷题笔记&#xff0c;发现LeetCode刷题都是套路呀&#xff0c;掌握这些套路之后&#xff0c;就变得非常简…

kubernetes高可用+harbor高可用

kubernetes高可用harbor高可用 基于kubeadm安装kubernetes高可用集群全部主机环境初始化双主节点部署keepalive双主节点初始化kubeadm在k8smaster1节点上初始化k8s在k8smaster2节点上做扩容操作 harbor高可用集群初始化harbor1节点安装环境在另一台节点上配置使用私有harbor仓库…

初学QT:使用QtDesigner绘制一个简单的界面(Day01)

关于Qt 打算在这里记录我学习qt过程中遇见的问题的收获 今天是学习qt的第一天&#xff0c;首先找了一个界面打算照着这个界面写一个一样的 因为是第一天&#xff0c;所以我用的是qt designer写的 其中遇到的问题&#xff1a; 设置背景图片 首先不能直接添加图片到背景图片中…

如何在华为OD机试中获得满分?Java实现【分界线】一文详解!

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: Java华为OD机试真题&#xff08;2022&2023) 文章目录 1. 题目描述2. 输入描述3. 输出描述…

在 Alma Linux 9 上安装 Node.js 的 3 种不同方法

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时&#xff0c;用于构建快速、可扩展的网络应用程序。在 Alma Linux 9 上安装 Node.js 可以为开发者提供强大的工具和库来开发服务器端应用程序。 本文将介绍三种不同的方法来安装 Node.js 在 Alma Linux 9 上。 1. 方法一…

LLMs的自动化工具系统(HuggingGPT、AutoGPT、WebGPT、WebCPM)

在前面两篇博文中已经粗略介绍了增强语言模型和Tool Learning&#xff0c;本篇文章看四篇代表性的自动化框架&#xff0c;HuggingGPT、AutoGPT、WebGPT、WebCPM。 Augmented Language Models&#xff08;增强语言模型&#xff09;Toolformer and Tool Learning&#xff08;LLM…

chatgpt赋能python:了解PythonSpace:Python编程中的重要概念

了解Python Space&#xff1a;Python编程中的重要概念 Python Space是Python编程的一个关键概念&#xff0c;可以帮助你更好地理解Python中的命名空间和作用域。在这篇文章中&#xff0c;我们将深入探讨Python Space&#xff0c;介绍命名空间的概念&#xff0c;讨论命名空间和…

支付系统设计四:支付核心设计03-快捷发送短信(失败转代扣)

文章目录 前言一、背景1. 应用架构2. 分层支撑机制 二、银行卡快捷支付1. 用户操作流程2. 系统执行流程--正常2.1 发送短信2.2 短信确认 3. 系统执行流程--异常3.1 异常环节3.1.1 路由失败3.1.2 调用支付渠道失败 3.2 异常处理3.2.1 路由失败3.2.2 调用支付渠道失败 4. 流程解析…