机器学习 Day03 Numpy基本使用

1.Numpy简介,ndarray介绍以及效率问题

  • 定义 :NumPy(Numerical Python)是一个开源的 Python 科学计算库,主要用于快速处理任意维度的数组。
  • 优势:支持常见的数组和矩阵操作,相比直接使用 Python 进行数值计算,代码更加简洁。
  • 核心对象 :使用ndarray对象来处理多维数组,该对象是一个快速且灵活的大数据容器,能够高效地存储和处理大量数据。
  • 简而言之,ndarray就是一个对象,来处理多维数组
python 复制代码
import numpy as np

# 创建ndarray
score = np.array(
    [[80, 89, 86, 67, 79],
     [78, 97, 89, 67, 81],
     [90, 94, 78, 67, 74],
     [91, 91, 90, 67, 69],
     [76, 87, 75, 67, 86],
     [70, 79, 84, 67, 84],
     [94, 92, 93, 67, 64],
     [86, 85, 83, 67, 80]])
  • np.array()是 NumPy 库中的一个函数,用于创建ndarray对象。
  • 函数的参数是一个嵌套的列表,外层列表的每个元素(即每个子列表)代表一名学生的各科成绩,从左到右依次对应语文、数学、英语、政治、体育成绩。
  • 执行这行代码后,会将这个嵌套列表转换为一个二维的ndarray对象,并赋值给变量score。此时,score就可以用来进行各种基于数组的操作,比如计算每门课的平均分、找出每个学生的最高分等。

ndarray对象特点体现

  • 同质性ndarray中的所有元素必须是相同类型。在这个成绩示例中,所有成绩都是整数类型。如果尝试混合不同类型的数据(比如将某个成绩写成字符串),NumPy 会自动进行类型转换(可能导致数据丢失或错误)。
  • 多维性 :这里创建的是二维ndarray,可以方便地表示表格型数据。同时,ndarray可以是任意维度,比如一维ndarray可以表示一组同类型的数值,三维ndarray可以用于表示图像数据(长、宽、通道维度)等。
  • 高效性ndarray在存储和处理大量同类型数据时,相比 Python 原生的列表更加高效,能够大大提升计算速度,这也是 NumPy 在科学计算中广泛应用的重要原因之一。

高效原因:

  • 内存块风格ndarray存储数据时,数据与数据的地址连续。因为其所有元素类型相同,内存可连续分配。而 Python 原生列表元素类型任意,只能通过寻址找下一个元素。这使得ndarray在批量操作数组元素时速度更快。虽然在通用性上不如 Python 原生列表,但在科学计算中,ndarray能减少循环语句,代码更简洁。
  • 支持并行化运算(向量化运算):NumPy 内置并行运算功能,当系统有多个核心时 ,进行某种计算时,NumPy 会自动并行计算,提高运算效率。
  • 效率远高于纯 Python 代码:NumPy 底层用 C 语言编写,内部解除了全局解释器锁(GIL),对数组的操作速度不受 Python 解释器限制,相比纯 Python 代码,执行效率更高

2.N维数组对象ndarray

2.1ndarray的属性(即对象的属性,类里边定义好的属性,用的时候就是已创建对象.属性,不加括号)

常用对象.shape和对象.dtype

2.2数组的形状

可以有n维

2.3数组类型(使用dtype可得类型)

ndarray对象必须类型相同

np.string_ 字符串类型

常用的就是np.int64/32 np.float64/32 np.string_ np.objext_

2.4基本操作

2.4.1数组生成

2.4.1.1 0-1数组

生成数组的函数介绍

  1. np.ones(shape, dtype) :用于创建一个指定形状(shape)和数据类型(dtype)的数组,数组元素全部初始化为 1。shape是一个整数或整数元组,表示数组的维度大小;dtype可选,指定数组元素的数据类型,默认是float64
  2. np.ones_like(a, dtype) :以给定数组a为模板,创建一个形状和a相同的数组,元素全部初始化为 1。同样,dtype可选,用于指定新数组的元素类型,若不指定,则沿用a的元素类型。
  3. np.zeros(shape, dtype) :创建一个指定形状(shape)和数据类型(dtype)的数组,元素全部初始化为 0。参数含义与np.ones类似。
  4. np.zeros_like(a, dtype) :根据给定数组a的形状,创建一个元素全部为 0 的数组。dtype可选,可改变新数组的元素类型。

代码示例

  1. ones = np.ones([4,8])
    • 这行代码使用np.ones函数创建一个二维数组ones。参数[4, 8]表示数组的形状,即 4 行 8 列。由于没有指定dtype,按照默认规则,数组元素的数据类型为float64
    • 从返回结果可以看到,数组中每个元素的值都是 1.0 ,符合np.ones函数的功能。
  2. np.zeros_like(ones)
    • 这行代码以数组ones为模板,使用np.zeros_like函数创建一个新的数组。新数组的形状和ones相同,都是 4 行 8 列。并且因为没有指定dtype,新数组的数据类型也和ones一样,为float64
    • 从返回结果可知,新数组的每个元素值都是 0.0 ,说明np.zeros_like函数成功创建了一个元素全为 0 且形状与ones一致的数组。

2.4.1.2 从现有数组生成

NumPy 中从现有数组生成新数组的方法:

  • 函数介绍
    • np.array(object, dtype):可以将输入的对象(如列表、元组等)转换为 NumPy 数组,dtype参数可选,用于指定数组的数据类型。当输入对象本身就是 NumPy 数组时,它会创建一个新的数组,新数组和原数组的数据相同。
    • np.asarray(a, dtype):将输入的对象转换为 NumPy 数组,若输入已经是 NumPy 数组且数据类型符合要求,则不会创建新的数组,而是返回原数组的引用(类似索引形式);若数据类型不匹配或输入不是 NumPy 数组,才会创建新数组。
  • 示例讲解
    • 先通过a = np.array([[1,2,3],[4,5,6]])创建了一个二维数组a
    • a1 = np.array(a):使用np.array对已有数组a进行操作,会创建一个新的数组a1a1a的数据内容一样。
    • a2 = np.asarray(a):使用np.asarray处理数组a,由于a已经是 NumPy 数组,这里不会真正创建新数组,a2只是a的一个引用,对aa2中一个的修改会反映在另一个上。
    • a1相当于深拷贝,a2相当于浅拷贝,改变a的值a1不变而a2变

2.4.1.3 生成固定范围数组

NumPy 中生成固定范围数组的三种方法:

1. np.linspace(start, stop, num, endpoint)

  • 功能:用于创建指定数量元素的等差数组。
  • 参数详解
    • start:序列的起始值。
    • stop:序列的终止值。
    • num:要生成的等间隔样本数量,默认为 50。
    • endpoint:序列中是否包含stop值,默认为True
  • 示例np.linspace(0, 100, 11) ,这里起始值start为 0,终止值stop为 100,num为 11,表示生成包含 11 个元素的数组。由于endpoint采用默认值True,所以数组中包含终止值 100。返回结果array([ 0., 10., 20., 30., 40., 50., 60., 70., 80., 90., 100.]) ,相邻元素差值为 10,是一个等差数组。

2. np.arange(start, stop, step, dtype)

  • 功能:创建指定步长的等差数组。
  • 参数详解
    • start:起始值(包含)。
    • stop:终止值(不包含)。
    • step:步长,默认值为 1。
    • dtype:数据类型,可选参数。
  • 示例np.arange(10, 50, 2) ,起始值start是 10,终止值stop是 50,步长step为 2。返回结果array([10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48]) ,数组从 10 开始,以步长 2 递增,直到小于 50 为止。

3. np.logspace(start, stop, num)

  • 功能:用于创建等比数列。
  • 参数详解
    • start:序列起始值的对数(底数默认为 10),即10 ** start 为序列的起始值。
    • stop:序列终止值的对数(底数默认为 10),即10 ** stop 为序列的终止值。
    • num:要生成的等比数列数量,默认为 50。
  • 示例np.logspace(0, 2, 3) ,这里start为 0,stop为 2,num为 3。起始值是10 ** 0 = 1,终止值是10 ** 2 = 100,生成包含 3 个元素的等比数列。返回结果array([ 1., 10., 100.]) ,相邻元素的比值为 10,是一个等比数列。

2.4.1.4 生成正态分布,均匀分布数组

正态分布创建方式

  1. np.random.randn(d0, d1, ..., dn)
    • 功能 :从标准正态分布(均值为 0,标准差为 1)返回一个或多个样本值。参数d0, d1, ..., dn用于指定输出数组的形状。
    • 示例 :如np.random.randn(2, 3)会生成一个形状为 (2, 3) 的数组,数组中的元素都从标准正态分布中随机采样得到。
  2. np.random.normal(loc=0.0, scale=1.0, size=None)(常用)
    • 功能:从指定均值和标准差的正态分布中随机采样。
    • 参数详解
      • loc:概率分布的均值,对应整个分布的中心,默认值为 0.0。
      • scale:概率分布的标准差,对应分布的宽度,scale越大分布越矮胖,scale越小分布越瘦高,默认值为 1.0。
      • size:输出的形状,默认为None,此时只输出一个值;若为整数或整数元组,则输出对应形状的数组。
    • 示例x1 = np.random.normal(1.75, 1, 100000000),这里指定均值loc为 1.75,标准差scale为 1,size为 100000000,即生成 1 亿个均值为 1.75,标准差为 1 的正态分布数据。
  3. np.random.standard_normal(size=None)
    • 功能:返回指定形状的标准正态分布(均值为 0,标准差为 1)的数组。
    • 示例np.random.standard_normal((3, 4))会生成一个形状为 (3, 4) 的标准正态分布数组。

正态分布示例绘图部分

python 复制代码
import matplotlib.pyplot as plt
import numpy as np

x1 = np.random.normal(1.75, 1, 100000000)
plt.figure(figsize=(20, 10), dpi=100)
plt.hist(x1, 1000)
plt.show()
  • 代码说明
    • 首先用np.random.normal生成数据x1
    • plt.figure(figsize=(20, 10), dpi=100)创建一个画布,设置大小为 (20, 10) 英寸,分辨率为 100 像素 / 英寸。
    • plt.hist(x1, 1000)绘制直方图,将x1的数据进行统计分组,这里设置了 1000 个 bins(区间),直观展示数据的分布状况。
    • plt.show()显示绘制的图像,可以看到数据呈现出以 1.75 为中心的正态分布形态。

均匀分布创建方式

  1. np.random.rand(d0, d1, ..., dn)
    • 功能 :返回 [0.0, 1.0) 内的一组均匀分布的数。参数d0, d1, ..., dn用于指定输出数组的形状。
    • 示例np.random.rand(2, 3)会生成一个形状为 (2, 3) 的数组,元素在 [0.0, 1.0) 之间均匀分布。
  2. np.random.uniform(low=0.0, high=1.0, size=None)(常用)
    • 功能 :从一个均匀分布[low, high)中随机采样,定义域是左闭右开,即包含low,不包含high
    • 参数详解
      • low:采样下界,默认值为 0.0。
      • high:采样上界,默认值为 1.0。注意是样本的上限不是X轴的
      • size:输出样本数目,为整数或元组类型,例如size=(m, n, k),则输出mnk个样本,缺省时输出 1 个值。
    • 示例x2 = np.random.uniform(-1, 1, 100000000),从 [-1, 1) 的均匀分布中采样 1 亿个数据。
  3. np.random.randint(low, high=None, size=None, dtype='l')
    • 功能:从一个均匀分布中随机采样,生成一个整数或 N 维整数数组。
    • 参数详解
      • low:取值范围的下限。
      • high:若不为None,取值范围是[low, high)之间的随机整数;若为None,则取值范围是[0, low)之间的随机整数。
      • size:输出的形状,默认为None,此时只输出一个值;若为整数或整数元组,则输出对应形状的数组。
      • dtype:输出数据的类型,默认是'l'(长整型)。
    • 示例np.random.randint(1, 10, (2, 3))会生成一个形状为 (2, 3) 的数组,元素是 1(包含)到 10(不包含)之间的随机整数。

2.4.2ndarray的切片和索引

注意切片包前不包后

很简单,在ndarray中用,间隔表示即可即对象[切片或者索引,切片或者索引 ,切片或者索引 , 切片或者索引,.....],索引就是a:b表示。

2.4.3 形状的修改

1. ndarray.reshape(shape, order)

  • 功能 :返回一个具有相同数据域,但形状不一样的视图。原数组和新数组共享数据内存,所以使用后原数组发生变化,且不会对行、列进行互换。order参数可选,用于指定在内存中如何排列元素,常见取值有'C'(按行优先,即 C 语言风格)和'F'(按列优先,即 Fortran 语言风格),默认是'C'
  • 注意事项:转换形状时,新形状的元素总数必须与原数组一致。
  • 示例
python 复制代码
import numpy as np

# 创建一个一维数组
stock_change = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20])

# 转换为5行4列的二维数组
new_array_1 = stock_change.reshape((5, 4))
print(new_array_1)

# 使用-1自动计算维度,转换为2行10列的二维数组
new_array_2 = stock_change.reshape((-1, 10))
print(new_array_2)

在上述代码中,reshape((5, 4))stock_change数组转换为 5 行 4 列的二维数组;reshape((-1, 10))-1表示让 NumPy 自动计算该维度的大小,从而得到 2 行 10 列的二维数组,因为总元素数是 20,另一维是 10,所以这一维就是 2。

2. ndarray.resize(new_shape)

  • 功能:直接修改数组本身的形状,修改后数组的元素个数需要和原来保持相同。同样不会对行、列进行互换。
  • 示例
python 复制代码
import numpy as np

stock_change = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20])

# 修改为5行4列的二维数组
stock_change.resize((5, 4))
print(stock_change.shape)  # 输出 (5, 4)
print(stock_change)

执行resize((5, 4))后,stock_change数组本身的形状被修改为 5 行 4 列,后续再访问stock_change.shape时,会得到新的形状(5, 4)

3. ndarray.T

  • 功能:实现数组的转置,即将数组的行和列进行互换。
  • 示例
python 复制代码
import numpy as np

stock_change = np.array([
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12],
    [13, 14, 15, 16],
    [17, 18, 19, 20]
])

# 获取转置后的形状
transposed_shape = stock_change.T.shape
print(transposed_shape)  # 输出 (4, 5)
print(stock_change.T)

在图片介绍的三种ndarray形状修改方法中,ndarray.resize(new_shape)会直接修改原数组的形状,数组内容也会相应按照新形状重新排布 ,对原数组影响明显;ndarray.reshape(shape, order)返回的是原数组的一个视图,虽然数组数据共享,但它不改变原数组本身形状;ndarray.T是转置操作,生成一个新的转置数组,原数组本身不受影响 。

2.4.4类型修改(对象.方法())

1. ndarray.astype(type)

  • 功能 :将数组中的元素类型转换为指定的type,并返回一个新的数组。原数组不会被修改,新数组和原数组的数据内容相同,但数据类型不同。type可以是 NumPy 中的各种数据类型,如np.int32np.float64等。
  • 示例
python 复制代码
import numpy as np

# 创建一个包含浮点数的数组
stock_change = np.array([1.1, 2.2, 3.3])
print("原数组:", stock_change)
print("原数组类型:", stock_change.dtype)

# 将数组类型转换为np.int32
new_stock_change = stock_change.astype(np.int32)
print("转换后数组:", new_stock_change)
print("转换后数组类型:", new_stock_change.dtype)

在上述代码中,stock_change原本是包含浮点数的数组,数据类型为float64(默认)。通过astype(np.int32)将其元素类型转换为 32 位整数,生成一个新数组new_stock_change,原数组stock_change保持不变。

2. ndarray.tostring([order]) 或者 ndarray.tobytes([order])

  • 功能 :这两个方法功能基本相同,用于将数组中的原始数据以字节的形式转换为 Python 字节对象。order参数可选,用于指定在内存中读取元素的顺序,常见取值有'C'(按行优先,即 C 语言风格)和'F'(按列优先,即 Fortran 语言风格),默认是'C'
  • 示例
python 复制代码
import numpy as np

# 创建一个二维数组
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[12, 3, 34], [5, 6, 7]]])
print("原数组:", arr)

# 将数组转换为字节对象
byte_obj = arr.tostring()
print("字节对象:", byte_obj)
print("字节对象类型:", type(byte_obj))

2.4.5数组去重

NumPy 中用于数组去重的np.unique()函数

函数功能

np.unique()函数用于去除数组中的重复元素,并返回一个包含唯一元素的新数组,且新数组中的元素会按照升序排列。它适用于一维数组,对于多维数组,会先将其展平(flatten)后再进行去重操作。

代码示例讲解

python 复制代码
import numpy as np

# 创建一个二维数组
temp = np.array([[1, 2, 3, 4], [3, 4, 5, 6]])

# 使用np.unique()函数去重
result = np.unique(temp)
print(result)

在上述代码中:

  • 首先创建了一个二维数组temp,其中包含重复的元素,如34
  • 然后调用np.unique(temp)temp数组进行去重操作。由于temp是二维数组,np.unique()会先将其展平为一维数组[1, 2, 3, 4, 3, 4, 5, 6],再去除重复元素,并按升序排列,最终返回的结果是array([1, 2, 3, 4, 5, 6])

使用np.unique()函数不会修改原数组。如图片中的示例代码,创建temp数组后调用np.unique(temp),只是基于temp数组的数据生成一个去重且排序后的新数组并返回,temp数组本身的元素和结构都保持不变 。可以通过下面补充的代码验证:

python 复制代码
import numpy as np
temp = np.array([[1, 2, 3, 4], [3, 4, 5, 6]])
original_temp = temp.copy()  # 复制一份原数组
result = np.unique(temp)
print("原数组:", temp)
print("原数组与复制的数组是否相等:", np.array_equal(temp, original_temp)) 

上述代码中,提前复制一份原数组original_temp,在调用np.unique(temp)后,对比原数组temporiginal_temp,会发现二者相等,说明np.unique()未对原数组做修改。

2.5ndarray运算

2.5.1. 逻辑运算

python 复制代码
import numpy as np

# 生成10名同学,5门功课的数据
score = np.random.randint(40, 100, (10, 5))

# 取出最后4名同学的成绩,用于逻辑判断
test_score = score[6:, 0:5]

# 逻辑判断,如果成绩大于60就标记为True,否则为False
bool_result = test_score > 60
print("逻辑判断结果:\n", bool_result)

# BOOL赋值,将满足条件的设置为指定的值-布尔索引
test_score[test_score > 60] = 1
print("赋值后的成绩:\n", test_score)
  • 首先使用np.random.randint(40, 100, (10, 5))生成一个形状为(10, 5)的二维数组score,表示 10 名同学 5 门功课的成绩,成绩范围在 40 到 100 之间。
  • 通过切片score[6:, 0:5]取出最后 4 名同学的成绩,存储在test_score中。
  • 使用test_score > 60进行逻辑判断,得到一个布尔类型的数组bool_result,其中成绩大于 60 的位置为True,否则为False
  • 利用布尔索引test_score[test_score > 60] = 1,将test_score中成绩大于 60 的元素赋值为 1。

2.5.2. 通用判断函数

np.all()
python 复制代码
import numpy as np

score = np.random.randint(40, 100, (10, 5))
# 判断前两名同学的成绩是否全及格
all_result = np.all(score[0:2, :] > 60)
print("np.all判断结果:", all_result)

np.all()函数用于判断数组中的所有元素是否都满足指定条件。这里np.all(score[0:2, :] > 60)判断前两名同学(第一维和第二维切片0:2)的所有成绩(第二维取全部:)是否都大于 60。如果所有元素都满足条件,返回True,否则返回False

np.any()
python 复制代码
import numpy as np

score = np.random.randint(40, 100, (10, 5))
# 判断前两名同学的成绩是否有大于80分的
any_result = np.any(score[0:2, :] > 80)
print("np.any判断结果:", any_result)

np.any()函数用于判断数组中是否至少有一个元素满足指定条件。np.any(score[0:2, :] > 80)判断前两名同学的成绩中是否存在大于 80 分的。如果有至少一个元素满足条件,返回True,否则返回False

2.5.3. np.where(三元运算符)

简单使用
python 复制代码
import numpy as np

score = np.random.randint(40, 100, (10, 5))
# 取前四名同学,前四门课程的成绩
temp = score[:4, :4]
# 成绩中大于60的置为1,否则为0
where_result = np.where(temp > 60, 1, 0)
print("np.where简单使用结果:\n", where_result)

np.where()函数根据条件返回不同的值。np.where(temp > 60, 1, 0)表示如果temp中的元素大于 60,就返回 1,否则返回 0。

结合复合逻辑

当需要进行复合逻辑判断时,结合np.logical_and(逻辑与)和np.logical_or(逻辑或)函数使用。np.logical_and(temp > 60, temp < 90)判断元素是否既大于 60 又小于 90,np.logical_or(temp > 90, temp < 60)判断元素是否大于 90 或者小于 60 ,然后np.where根据这些复合条件返回相应的值。

python 复制代码
import numpy as np

score = np.random.randint(40, 100, (10, 5))
temp = score[:4, :4]
# 成绩中大于60且小于90的换为1,否则为0
where_and_result = np.where(np.logical_and(temp > 60, temp < 90), 1, 0)
print("np.where结合logical_and结果:\n", where_and_result)

# 成绩中大于90或小于60的换为1,否则为0
where_or_result = np.where(np.logical_or(temp > 90, temp < 60), 1, 0)
print("np.where结合logical_or结果:\n", where_or_result)

2.5.4. 统计运算

  • min(a, axis) :返回数组a的最小值,若指定axis参数(axis=0表示按列,axis=1表示按行),则返回沿指定轴的最小值。
  • max(a, axis) :返回数组a的最大值,同样可根据axis参数沿指定轴返回最大值。
  • median(a, axis) :计算数组a沿指定轴的中位数。
  • mean(a, axis, dtype) :计算数组a沿指定轴的算术平均值,dtype参数可选,用于指定计算时的数据类型。
  • std(a, axis, dtype) :计算数组a沿指定轴的标准差。
  • var(a, axis, dtype) :计算数组a沿指定轴的方差。

学生成绩统计运算案例

python 复制代码
import numpy as np

# 生成10名同学,5门功课的数据
score = np.random.randint(40, 100, (10, 5))

# 取前四名学生的成绩
temp = score[:4, 0:5]

# 计算各科成绩的最大值
max_scores = np.max(temp, axis=0)
print("前四名学生, 各科成绩的最大分:", max_scores)

# 计算各科成绩的最小值
min_scores = np.min(temp, axis=0)
print("前四名学生, 各科成绩的最小分:", min_scores)

# 计算各科成绩的标准差(衡量波动情况)
std_scores = np.std(temp, axis=0)
print("前四名学生, 各科成绩波动情况:", std_scores)

# 计算各科成绩的平均分
mean_scores = np.mean(temp, axis=0)
print("前四名学生, 各科成绩的平均分:", mean_scores)
  • 首先使用np.random.randint(40, 100, (10, 5))生成一个形状为(10, 5)的二维数组score,代表 10 名学生 5 门课程的成绩,成绩范围在 40 到 100 之间。
  • 通过切片score[:4, 0:5]获取前四名学生的成绩,存储在temp中。
  • 分别调用np.max(temp, axis=0)np.min(temp, axis=0)np.std(temp, axis=0)np.mean(temp, axis=0),计算出这四名学生各科成绩的最大值、最小值、标准差和平均分。这里axis=0表示按列统计,即对每一门课程的成绩进行统计。

获取最值对应索引的函数

  • np.argmax(a, axis) :返回数组a沿指定轴(axis=0/1)的最大值的索引。
  • np.argmin(a, axis) :返回数组a沿指定轴的最小值的索引。

查找某科最高分对应的学生案例

python 复制代码
import numpy as np

# 生成10名同学,5门功课的数据
score = np.random.randint(40, 100, (10, 5))

# 取前四名学生的成绩
temp = score[:4, 0:5]

# 获取各科成绩最高分对应的学生下标
max_indexes = np.argmax(temp, axis=0)
print("前四名学生, 各科成绩最高分对应的学生下标:", max_indexes)

2.6数组的运算

1. 数组与数的运算

python 复制代码
import numpy as np

# 创建一个二维数组
arr = np.array([[1, 2, 3, 2, 1, 4], [5, 6, 1, 2, 3, 1]])

# 数组与数相加
result1 = arr + 1
print("数组与1相加的结果:\n", result1)

# 数组与数相除
result2 = arr / 2
print("数组与2相除的结果:\n", result2)

# 创建一个Python列表
a = [1, 2, 3, 4, 5]

# 列表与数相乘
result3 = a * 3
print("列表与3相乘的结果:", result3)
  • 在 NumPy 中,数组与数的运算会将数应用到数组的每个元素上。如arr + 1会把数组arr中的每个元素都加 1,arr / 2会将每个元素除以 2 。
  • 对比之下,Python 列表与数相乘(如a * 3),是将列表中的元素重复指定的次数,和 NumPy 数组的运算规则不同。

2. 数组与数组的运算

python 复制代码
import numpy as np

# 创建两个二维数组
arr1 = np.array([[1, 2, 3, 2, 1, 4], [5, 6, 1, 2, 3, 1]])
arr2 = np.array([[1, 2, 3, 4], [3, 4, 5, 6]])

一般情况下,两个数组进行运算要求形状(shape)完全相同,图片中的arr1arr2形状不同,直接运算会报错。但如果满足广播机制也可以进行运算

3. 广播机制

python 复制代码
import numpy as np

# 创建两个形状不同的数组
arr1 = np.array([[0], [1], [2], [3]])
print("arr1的形状:", arr1.shape)

arr2 = np.array([1, 2, 3])
print("arr2的形状:", arr2.shape)

# 数组相加
result = arr1 + arr2
print("相加的结果:\n", result)
  • 当数组形状不完全相同时,广播机制会发挥作用。arr1形状是(4, 1)arr2形状是(1,3)
  • 广播机制会扩展数组,使它们的形状兼容以便进行运算。这里arr1会在列方向扩展,变为(4,3)arr2会在行方向扩展,变为(4,3)最终二者都扩展为(4, 3)的形状再进行对应元素相加。
  • 广播机制满足的条件:一是数组的某一维度等长;二是其中一个数组的某一维度为 1 。若不满足这些条件,如A(1 维数组长度为 10)、B(1 维数组长度为 12)、A(2 维数组2×1)、B(3 维数组8×4×3),则数组不匹配,无法通过广播机制运算。进行对比时要一个一个对比,每个位置必需都满足条件比如2*4*1与2*1*6满足因为(1,6)(4,1)(2,2)都满足条件。注意如果维度不同,低维的按1处理即可。

2.7矩阵的运算

2.7.1. 矩阵乘法 API 函数介绍

  • np.matmul:用于执行矩阵乘法运算。它遵循严格的矩阵乘法规则,对于二维数组,就是标准的矩阵乘法;对于更高维度的数组,它会把最后两个维度视为矩阵进行乘法运算,而前面的维度保持不变。
  • np.dot :也可以进行矩阵乘法运算,但它的行为在处理一维数组和高维数组时,与np.matmul略有不同。对于二维数组,np.dotnp.matmul的功能类似,都是执行标准的矩阵乘法;对于一维数组,np.dot计算的是它们的内积。

2.7.2. 代码示例讲解

python 复制代码
import numpy as np

# 创建一个二维数组a,形状为(7, 2)
a = np.array([[80, 86],
              [82, 80],
              [85, 78],
              [90, 90],
              [82, 90],
              [78, 80],
              [92, 94]])

# 创建一个二维数组b,形状为(2, 1)
b = np.array([[0.7], [0.3]])

# 使用np.matmul进行矩阵乘法
result_matmul = np.matmul(a, b)
print("使用np.matmul的结果:\n", result_matmul)

# 使用np.dot进行矩阵乘法
result_dot = np.dot(a, b)
print("使用np.dot的结果:\n", result_dot)
  • 首先创建了两个数组aba是一个形状为(7, 2)的二维数组,b是一个形状为(2, 1)的二维数组。在矩阵乘法中,要求第一个矩阵的列数等于第二个矩阵的行数,这里a的列数为 2,b的行数为 2,满足矩阵乘法的条件。
  • 然后分别使用np.matmul(a, b)np.dot(a, b)进行矩阵乘法运算。从输出结果可以看到,在这种二维数组且满足矩阵乘法规则的情况下,np.matmulnp.dot得到的结果是相同的。这是因为对于二维数组的标准矩阵乘法,这两个函数的功能一致 。但在处理一维数组或更复杂的高维数组时,它们的表现会有差异,例如当处理一维数组时,np.dot计算内积,而np.matmul则会报错,因为它要求输入至少是二维的矩阵形式 。
相关推荐
蹦蹦跳跳真可爱58913 分钟前
Python----计算机视觉处理(Opencv:自适应二值化,取均值,加权求和(高斯定理))
人工智能·python·opencv·计算机视觉
轻松Ai享生活26 分钟前
从代码粘贴侠到优雅的Coder? - 3个大神教我的脱坑不传之秘
人工智能·面试·程序员
机器之心37 分钟前
GPT4规模大模型落地,Meta提ExFM框架:万亿参数基础大模型的工业级落地成为可能
人工智能·openai
Scabbards_39 分钟前
理解知识如何在大型Vision-Language Models 中演化
人工智能·语言模型·自然语言处理
机器之心42 分钟前
OpenAI突然发布智能体API!支持网络和文件搜索以及computer use
人工智能·openai
noedn43 分钟前
测试大语言模型在嵌入式设备部署的可能性-ollama本地部署测试
人工智能·语言模型·自然语言处理
PawSQL1 小时前
推理模型对SQL理解能力的评测:DeepSeek r1、GPT-4o、Kimi k1.5和Claude 3.7 Sonnet
java·数据库·人工智能·sql·sql优化·pawsql·deepseek
蜂耘1 小时前
智元GO-1大模型,开启具身智能新纪元
人工智能·机器人·业界资讯
量子纠缠BUG1 小时前
深度解读:OpenAI发布GPT-5的技术突破与商业影响
人工智能·gpt
枫子有风1 小时前
深度学习实验
人工智能·深度学习