Numpy科学计算库介绍
2024-01-03 07:56:53

Numpy科学计算库介绍

NumPy是Python中用于科学计算的重要基础库。它提供了多维数组对象、各种派生对象(如掩码数组和矩阵),以及丰富的数组操作函数,包括数学、逻辑、形状操作、排序、选择、I/O、离散傅里叶变换、基本线性代数、基本统计计算和随机模拟等功能。

NumPy的核心组件是ndarray对象,它封装了具有同一数据类型的n维数组。这些操作通常在底层编译代码中执行,以提高性能。与Python列表不同,NumPy数组在创建时具有固定的大小,如果需要更改数组的大小,将创建一个新数组,原始数组将被删除。

另一个重要区别是NumPy数组要求所有元素具有相同的数据类型,因此它们在内存中占用相同的大小。然而,也有例外,允许数组包含不同大小元素的对象,这在Python和NumPy中都得到支持。

NumPy数组极大地促进了对大规模数据进行高级数学和其他运算。通常,与使用Python内置序列相比,这些操作更高效且需要更少的代码。

越来越多基于Python的科学和数学库开始广泛采用NumPy数组。虽然它们通常支持Python序列输入,但它们通常会在处理前将其转换为NumPy数组,并输出NumPy数组。因此,为了有效地使用当今的大多数科学和数学软件,不仅需要了解如何使用Python内置序列类型,还需要了解如何使用NumPy数组。这使NumPy成为进行科学计算和数据处理的不可或缺的工具。

Numpy开发环境搭建

Numpy是第三方程序库,所以在使用Numpy之前必须安装 Numpy 。
如果使用的 Anaconda Python 开发环境,那么Numpy 已经集成到Anaconda 环境中了,不需要再安装。
如果使用的是官方开发环境,可以使用 pip 命令安装 Numpy ,语法格式如下:

1
pip install numpy

通过命令导入不会报错

1
import numpy as np

检查是否安装成功

1
2
3
import numpy as np
a = np.arange(10)
print(a)

在上面的程序中只涉及numpy模块中的一个 arange 函数,该函数可以传入一个整数类型的参数 n ,函数返回值看着像一个列表,其实返回值类型是 numpy.ndarray 。这是 Numpy 中特有的数组类型。如果传入 arange 函数的参数值是 n,那么 arange 函数会返回 0 到 n- 1 的 ndarray 类型的数组。

数组的创建

array创建

numpy 模块的array 函数可以生成多维数组。例如如果要生成一个二维数组,需要向 array 函数传递一个列表类型的参数。每一个列表元素是一维的 ndarray 类型数组,作为二维数组的行。另外,通过 ndarray 类的 shape 属性可以获得数组每一维的元素个数(元组形式),也可以通过 shape[n]形式获得每一维的元素个数,其中 n 是维度,从 0 开始。

语法格式:

1
>numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
名称 描述
object 数组或嵌套的数列
dtype 数组元素的数据类型,可选
copy 对象是否需要复制,可选
order 创建数组的样式,C 为行方向,F 为列方向,A 为任意方向 (默认)
subok 默认返回一个与基类类型一致的数
ndmin 组指定生成数组的最小维度
1
2
3
4
5
6
7
8
9
10
# 创建一维度数组
a = np.array([1,2,3,4,5,6])
print(a)
print(f'数组的维度:{a.shape}')

"""
输出:
[1 2 3 4 5 6]
数组的维度:(6,)
"""
1
2
3
4
5
6
7
8
9
10
11
12
# 创建二维数组
b = np.array([[1,2,3],[4,5,6],[7,8,9]])
print(b)
print(f'数组的维度:{b.shape}')

"""
输出:
[[1 2 3]
[4 5 6]
[7 8 9]]
数组的维度:(3, 3)
"""
1
2
3
4
5
6
7
8
9
10
# array()函数ndmin参数的使用
c = np.array([1,2,3,4,5,6],order='C',ndmin=2,dtype="float32")
print(c)
print(f'数组的维度:{c.shape}')

"""
输出:
[[1. 2. 3. 4. 5. 6.]]
数组的维度:(1, 6)
"""

arange 创建

使用arange函数创建数值范围并返回ndarray对象,函数语法格式如下:

参数 描述
start 起始值,默认值0
stop 终止值(不包含)
step 步长,默认为1
dtype 返回ndarray的数据类型,如果没有提供,则会使用输入数据的类型。
1
numpy.arange(start, stop, step, dtype)
1
2
3
4
5
6
7
8
9
# arange()函数创建数组
import numpy as np
x = np.arange(0,6,dtype="int32")
print(x)

"""
输出:
[0 1 2 3 4 5]
"""
1
2
3
4
5
6
7
8
# arange()函数指定起始值,终止值及步长
x = np.arange(10,20,2,dtype="float32")
print(x)

"""
输出:
[10. 12. 14. 16. 18.]
"""
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# arange()函数创建二维数组
b = np.array([np.arange(1,4),np.arange(4,7),np.arange(7, 10)])
print(b)
print('b 数组的维度:',b.shape)

"""
输出:
[[1 2 3]
[4 5 6]
[7 8 9]]

shape
b 数组的维度: (3, 3)
"""

随机数创建

numpy中的random模块包含了很多方法可以用来产生随机数

函数 说明
seed 确定随机生成器种子
permutation 返回一个序列的随机排列或返回一个随机排列的范围
shuffle 对一个序列就地随机排列
rand 产生均匀分布的样本值
randint 该方法有三个参数 low、high、size 三个参数。默认high是None,如果只有 low,那范围就是[0,low)。如果有high,范围就是[low,high)。
random(size=None) 该方法返回[0.0, 1.0)范围的随机数
randn(d0, d1, …, dn) randn函数返回一个或一组样本,具有标准正态分布(期望为0,方差为1)。dn表格每个维度,返回值为指定维度的array
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#numpy.random.random(size=None)的使用
#numpy.random.random(size=None)
#返回[0.0, 1.0)范围的随机数

import numpy as np
print('生成一维 (4,) 的随机数组:')
x = np.random.random(size=4)
print(x)
print('生成二维 (3,4) 的随机数组:')
y = np.random.random(size=(3,4))
print(y)

"""
输出:
生成一维 (4 ,) 的随机数组:
[0.37049582 0.61621627 0.27036921 0.00296876]
生成二维 (3,4) 的随机数组:
[[0.3034857 0.01716423 0.33466199 0.63552479]
[0.98441398 0.68298795 0.2157518 0.26527395]
[0.09824638 0.37760538 0.23878191 0.80700919]]
"""
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import numpy as np
#numpy.random.randint()的使用
#生成 [0,low)范围的随机整数
x = np.random.randint(5,size=10)
print(x)
#生成[low,high)范围的随机整数
y = np.random.randint(5, 10,size=10)
print(y)

#生成[low,high)范围的 2*4 的随机整数
z = np.random.randint(5, 10,size=(2,4))
print(z)

"""
输出:
[1 3 1 1 4 0 1 3 1 1]
[6 7 9 8 6 7 5 7 6 5]
[[7 6 5 7]
[9 8 7 8]]
"""
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# randn 函数返回一个或一组样本,具有标准正态分布
import numpy as np
x = np.random.randn()
print(x)
y = np.random.randn(2,4)
print(y)
z = np.random.randn(2,3,4)
print(z)

"""
输出:
0.7570368386296304
[[-0.27404107 1.79284787 -0.610148 -0.61133028]
[ 1.22979542 1.28548447 -0.34606341 -2.39747891]]
[[[-0.03775439 -0.19744339 0.22950662 -1.04011106]
[ 1.1794495 -0.49567408 1.15366031 0.10319471]
[-0.47862608 -0.01704501 0.36087672 -1.25516722]]

[[-0.71899511 -0.04387895 0.08553971 0.96227697]
[-1.49119983 0.23293101 0.99262119 -1.78993593]
[ 0.06060192 0.96005764 0.22820192 0.44324335]]]
"""
1
2
3
4
5
6
7
8
9
10
11
12
13
# np.random.normal()的使用
import numpy as np
#正态分布 (高斯分布) loc:期望 scale:标准差, size 形状
print(np.random.normal(loc=3,scale=4,size=(2,2,3)))

"""
输出:
[[[-0.78820026 3.88893028 -3.16987099]
[-4.8275663 4.97645244 2.2244763 ]]

[[ 5.49661068 1.00436401 1.01827579]
[ 1.26098958 3.42404252 4.85621482]]]
"""

其他方式创建

numpy.zeros创建一个由0填充的数组

ndarray 数组除了可以使用底层ndarray构造器来创建外,也可以通过以下几种方式来创建。zerosnumpy.zeros创建指定大小的数组,数组元素以0来填充:

1
numpy.zeros(shape, dtype = float)

zeros()函数创建数组:

1
2
3
4
5
6
7
8
9
10
import numpy as np
x = np.zeros(5)
print(x)

#设置类型为整数
y = np.zeros((5,),dtype=int)
print(y)

z = np.zeros((2,2))
print(z)

numpy.ones创建一个由1填充的数组

numpy.ones 创建指定形状的数组,数组元素以1来填充

1
numpy.ones(shape, dtype = int)

ones()函数创建数组:

1
2
3
4
5
import numpy as np
x = np.ones(5)
print(x)
y = np.ones((3,4),dtype=int)
print(y)

numpy.empty创建一个无填充的数组

numpy.empty()方法用来创建一个指定形状 (shape) 、数据类型 (dtype) 且未初始化 的数组,里面的元素的值是之前内存的值

1
numpy.empty(shape, dtype = float)
参数 描述
shape 数组形状
dtype 数据类型,可选
order 有”C”和”F”两个选项,分别代表,行优先和列优先,在计算机内存中的存储元
素的顺序。
1
2
3
import numpy as np
x = np.empty([3,2],dtype=int)
print(x)

numpy.linspace创建一个等差数列数组

linspace 函数用于创建一个一维数组,数组是一个等差数列构成的,格式如下

1
np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
参数 描述
start 序列的起始值
stop 序列的终止值,如果 endpoint 为 true,该值包含于数列中
num 要生成的等步长的样本数量,默认为 50
endpoint 该值为 true 时,数列中中包含 stop 值,反之不包含,默认是True。
retstep 如果为 True 时,生成的数组中会显示间距,反之不显示
dtype ndarray 的数据类型

linspace()函数创建等差数列:

1
2
3
4
5
6
7
8
import numpy as np
x = np.linspace(1, 10, 10)
print(x)

"""
输出:
[ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]
"""

linspace()函数创建等差数列指定 endpoint 参数为 true:

1
2
3
import numpy as np
x = np.linspace(10, 20, 5, endpoint = True, retstep = True)
print(x)

numpy.logspace创建一个对数间隔的数字序列数组

numpy.logspace 函数用于创建一个于等比数列。格式如下

1
np.logspace(start, stop, num=50, endpoint = True, base = 10.0, dtype = None)
参数 描述
start 序列的起始值为: base ** start
stop 序列的终止值为: base ** stop。如果 endpoint 为 true,该值包含于数列中
num 要生成的等步长的样本数量,默认为 50
endpoint 该值为 true 时,数列中中包含 stop 值,反之不包含,默认是True。
base 对数 log 的底数。
dtype ndarray 的数据类型

使用np.logspace创建对数间隔的数字序列:

1
2
3
4
5
6
7
8
9
10
11
12
import numpy as np

# 创建一个包含5个元素的对数间隔序列,底数为10
logspace_array = np.logspace(1, 3, 5)
print(logspace_array)

​```
输出:
[ 10. 31.6227766 100. 316.22776602 1000. ]
​```

# 在上述代码中,我们使用np.logspace生成了一个包含5个元素的对数间隔序列,起始点是10^1(即10)、终止点是10^3(即1000),共生成5个数字。默认情况下,底数是10。

切片和索引

ndarray 对象的内容可以通过索引或切片来访问和修改,与Python中list的切片操作一样。ndarray数组可以基于0-n的下标进行索引,并设置 start, stop及step参数进行,从原数组中切割出一个新数组。

1
2
3
4
5
6
7
8
9
10
11
# 一维数组切片和索引的使用
import numpy as np
x=np.arange(10)
print('原数组:',x)

[开始切片位置:结束切片的位置:步长]

y = x[2:7:2]
z = x[2:]
print('对数组进行[2:7:2]切片:',y)
print('对数组进行[2:]切片:',z)
1
2
3
4
5
6
7
8
9
10
11
12
13
# 二维数组索引的使用
import numpy as np
x = np.arange(1,13)

# 把一维数组转换形状成二维数组
a = x.reshape(4,3)

print('数组元素')
print(a)
print('获取第二行')
print(a[1])
print('获取第三行第二列')
print(a[2][1])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 二维数组切片的使用
import numpy as np
x = np.arange(1, 13)
a = x.reshape(4,3)
print('数组元素')
print(a)
#使用索引获取
print('所有行的第二列')

# [ 行开始:行结束:行步长 , 列开始:列结束:行步长 ]

print(a[:, 1])
print('奇数行的第一列')
print(a[::2,0])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 二维数组索引的使用
import numpy as np
a = np.arange(1,13).reshape(4,3)
print('数组元素')
print(a)
print('获取第三行第二列的结果:',a[2,1])
print('同时获取第三行第二列,第四行第一列')
print('分别获取:',np.array((a[2, 1],a[3,0])))
print('第一个元组是行索引,第二个元组是列索引获取:',a[(2,3),( 1,0)])

"""
输出:

数组元素
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
获取第三行第二列的结果: 8
同时获取第三行第二列,第四行第一列
分别获取: [ 8 10]
第一个元组是行索引,第二个元组是列索引获取: [ 8 10]
"""
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
30
31
32
# 负索引的使用
import numpy as np
x = np.arange(1, 13).reshape(4,3)
print('数组元素')
print(x)
print('获取最后一行')
print(x[-1])
print('行进行倒序')
print(x[::-1])
print('行列都倒序')
print(x[::-1, ::-1])

"""
输出:
数组元素
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
获取最后一行
[10 11 12]
行进行倒序
[[10 11 12]
[ 7 8 9]
[ 4 5 6]
[ 1 2 3]]
行列都倒序
[[12 11 10]
[ 9 8 7]
[ 6 5 4]
[ 3 2 1]]
"""

所有切片取出来的数组,即使你把它赋值给了新的变量,它仍是原来数组的视图。

改变数组的维度

处理数组的一项重要工作就是改变数组的维度,包含提高数组的维度和降低数组的维度,还包括数组的转置。Numpy 提供的大量 API 可以很轻松地完成这些数组的操作。 例如,通过 reshape 方法可以将一维数组变成二维、三维或者多维数组。通过 ravel 方法或 flatten 方法可以将多维数组变成一维数组。改变数组的维度还可以直接设置 Numpy 数组的 shape 属性 (元组类型) ,通过 resize 方法也可以改变数组的维度。

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
# 改变数组的维度
import numpy as np
#创建一维的数组
a = np.arange(24)
print(a)
print('数组 a 的维度:',a.shape)
print('-'*30)

#使用 reshape 将一维数组变成三维数组
b = a.reshape(2,3,4)
print(b)
print('数组 b 的维度:',b.shape)
print('-'*30)

#将 a 变成二维数组
c = a.reshape(3,8)
print(c)
print('数组 c 的维度:',c.shape)
print('-'*30)

#使用 ravel 函数将三维的 b 变成一维的数组 浅拷贝
a1 = b.ravel()
print(a1)
print('-'*30)

#使用 flatten 函数将二维的 c 变成一维的数组 完全复制
a2 = c.flatten()
print(a2)
print('-'*30)

为什么引入ndarray数组

NumPy最重要的一个特点是其N维数组对象ndarray,它是一系列同类型数据的集合,以0下标为开始进行集合中元素的索引。

  • ndarray对象是用于存放同类型元素的多维数组。
  • ndarray中的每个元素在内存中都有相同存储大小的区域。
  • ndarray内部由以下内容组成:
    • 一个指向数据 (内存或内存映射文件中的一块数据) 的指针。
    • 数据类型或 dtype,描述在数组中的固定大小值的格子。
    • 一个表示数组形状 ( shape) 的元组,表示各维度大小的元组
属性 说明
ndarray.ndim 秩,即轴的数量或维度的数量
ndarray.shape 数组的维度,对于矩阵,n 行 m 列
ndarray.size 数组元素的总个数,相当于 shape 中 n*m 的值
ndarray.dtype ndarray 对象的元素类型
ndarray.itemsize ndarray 对象中每个元素的大小,以字节为单位
ndarray.flags ndarray 对象的内存信息
ndarray.real ndarray 元素的实部
ndarray.imag ndarray 元素的虚部
ndarray.data 包含实际数组元素的缓冲区,由于一般通过数组的索引获取元素,所以通常不需要使用这个属性。

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

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

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

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

Python原生的list:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 假设有两个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

print(a)

"""
输出:
[2, 3, 4, 5, 6]
"""

使用ndarray:

1
2
3
4
5
6
7
8
9
import numpy as np
a = np.array([1, 2, 3, 4, 5])
a = a + 1
print(a)

"""
输出:
array([2, 3, 4, 5, 6])
"""

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

计算a和b中对应位置元素的和,是否可以这么写?

1
2
3
4
5
6
7
8
9
10
a = [1, 2, 3, 4, 5]
b = [2, 3, 4, 5, 6]
c = a + b
# 检查输出发现,不是想要的结果
print(c)

"""
输出:
[1, 2, 3, 4, 5, 2, 3, 4, 5, 6]
"""

使用for循环,完成两个list对应位置元素相加:

1
2
3
4
5
6
7
8
9
c = []
for i in range(5):
c.append(a[i] + b[i])
print(c)

"""
输出:
[3, 5, 7, 9, 11]
"""

使用numpy中的ndarray完成两个ndarray相加:

1
2
3
4
5
6
7
8
9
10
import numpy as np
a = np.array([1, 2, 3, 4, 5])
b = np.array([2, 3, 4, 5, 6])
c = a + b
print(c)

"""
输出:
array([ 3, 5, 7, 9, 11])
"""

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

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

自动广播机制,1维数组和2维数组相加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# d是二维数组
d = np.array([
[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10]
])

# c是一维数组
c = np.array([ 4, 6, 8, 10, 12])
e = d + c
print(e)

"""
输出:
array([[ 5, 8, 11, 14, 17],
[10, 13, 16, 19, 22]])
"""

查看ndarray数组的属性

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

  • shape:数组的形状 ndarray.shape,1维数组$(N, )$,2维数组$(M, N)$,$3维数组(M, N, K)$。
  • dtype:数组的数据类型。
  • size:数组中包含的元素个数ndarray.size,其大小等于各个维度的长度的乘积。
  • ndim:数组的维度大小ndarray.ndim, 其大小等于ndarray.shape所包含元素的个数。
1
2
3
4
5
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import numpy as np
b = np.random.rand(10, 10)

b.shape
# 输出:
# (10, 10)

b.size
# 输出:
# 100

b.ndim
# 输出:
# 2

b.dtype
# 输出:
# dtype('float64')

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

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

1
2
3
4
5
6
7
8
9
10
11
12
# 转化数据类型
# 位bit 字节byte
# 1字节 = 8位
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)

ndarray数组的基本运算

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

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

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

1
2
3
# 标量除以数组,用标量除以数组的每一个元素
arr = np.array([[1., 2., 3.], [4., 5., 6.]])
1./arr
array([[1.        , 0.5       , 0.33333333],
       [0.25      , 0.2       , 0.16666667]])
1
2
3
# 标量乘以数组,用标量乘以数组的每一个元素
arr = np.array([[1., 2., 3.], [4., 5., 6.]])
2. * arr
array([[ 2.,  4.,  6.],
       [ 8., 10., 12.]])
1
2
3
# 标量加上数组,用标量加上数组的每一个元素
arr = np.array([[1., 2., 3.], [4., 5., 6.]])
2.0 + arr
array([[3., 4., 5.],
       [6., 7., 8.]])
1
2
3
# 标量减去数组,用标量减去数组的每一个元素
arr = np.array([[1., 2., 3.], [4., 5., 6.]])
2.0 - arr
array([[ 1.,  0., -1.],
       [-2., -3., -4.]])

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

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

1
2
3
4
# 数组 减去 数组, 用对应位置的元素相减
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.]])
1
2
3
4
# 数组 加上 数组, 用对应位置的元素相加
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.]])
1
2
# 数组 乘以 数组,用对应位置的元素相乘
arr1 * arr2
array([[ 11.,  24.,  39.],
       [ 84., 110., 138.]])
1
2
# 数组 除以 数组,用对应位置的元素相除
arr1 / arr2
array([[0.09090909, 0.16666667, 0.23076923],
       [0.19047619, 0.22727273, 0.26086957]])
1
2
# 数组开根号,将每个位置的元素都开根号
arr ** 0.5
array([[1.        , 1.41421356, 1.73205081],
       [2.        , 2.23606798, 2.44948974]])

ndarray数组的统计方法

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

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

说明:

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


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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# 计算均值,使用arr.mean() 或 np.mean(arr),二者是等价的
arr = np.array([[1,2,3], [4,5,6], [7,8,9]])

# 平均:所有元素的总和是1+2+3+4+5+6+7+8+9=45,总共有9个元素,所以均值为45/9=5.0
arr.mean(), np.mean(arr)
"""
输出:
(5.0, 5.0)
"""

# 求和
arr.sum(), np.sum(arr)
"""
输出:
(45, 45)
"""

# 求最大值
arr.max(), np.max(arr)
"""
输出:
(9, 9)
"""

# 求最小值
arr.min(), np.min(arr)
"""
输出:
(1, 1)
"""

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

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

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

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

# 在整个数组中找到最大值的索引
arr.argmax()
"""
输出:
8
"""

# 沿着每一列找到最大值的索引
arr.argmax(axis=0)
"""
输出:
[2 2 2]
"""

# 沿着每一行找到最大值的索引
arr.argmax(axis=1)
"""
输出:
[2 2 2]
"""

numpy 转置

转置: 把列转换为行

在NumPy中,可以使用transpose()函数或.T属性来实现数组的转置操作。转置操作会交换数组的维度顺序,将行变为列,列变为行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import numpy as np

arr = np.array([
[1, 2, 3],
[4, 5, 6]
])
transposed_arr = np.transpose(arr)
# 或者使用简化形式:transposed_arr = arr.transpose()

print(arr)
"""
输出:
[[1 2 3]
[4 5 6]]
"""

print(transposed_arr)
"""
输出:
[[1 4]
[2 5]
[3 6]]
"""
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import numpy as np

arr = np.array([[1, 2, 3], [4, 5, 6]])
transposed_arr = arr.T

print(arr)
"""
输出:
[[1 2 3]
[4 5 6]]
"""

print(transposed_arr)
"""
输出:
[[1 4]
[2 5]
[3 6]]
"""

numpy乘法

在NumPy中,dot()函数用于计算两个数组的点积(dot product),也可以用于计算矩阵乘法。

对于一维数组,dot()计算的是它们的内积(内点积),结果是一个标量值。对于二维数组(矩阵),dot()计算的是矩阵乘法,结果是一个新的二维数组。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import numpy as np

arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
dot_product = np.dot(arr1, arr2)

print(dot_product) # 输出: 32

"""
计算过程如下:

arr1的元素是 [1, 2, 3],arr2的元素是 [4, 5, 6]。对应位置的元素相乘:
1 * 4 = 4
2 * 5 = 10
3 * 6 = 18

将上述结果相加:4 + 10 + 18 = 32
"""
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import numpy as np

arr1 = np.array([
[1, 2],
[3, 4]
])

arr2 = np.array([
[5, 6],
[7, 8]
])
matrix_product = np.dot(arr1, arr2)
print(matrix_product)

"""
计算第一个元素(第一行的第一列):(1 * 5) + (2 * 7) = 5 + 14 = 19
计算第二个元素(第一行的第二列):(1 * 6) + (2 * 8) = 6 + 16 = 22
计算第三个元素(第二行的第一列):(3 * 5) + (4 * 7) = 15 + 28 = 43
计算第四个元素(第二行的第二列):(3 * 6) + (4 * 8) = 18 + 32 = 50

所以,matrix_product将包含以下矩阵:
array([[19, 22],
[43, 50]])
"""