【NumPy 入门:常用函数与方法总结】


前言

NumPy 是一个强大的科学计算库,提供了丰富的函数和方法,用于高效地处理数组和矩阵操作,本文是NumPy 库中入门的一些常用函数和方法。


1、np.array() 函数

np.array() 函数用于创建 NumPy 数组(1)。它期望接收一个对象(通常是列表、元组或其他数组),然后将该对象转换为 NumPy 数组。

错误示例:

import numpy as np

# 错误用法,传递了多个参数
a = np.array(1, 2, 3, 4)

正确示例:

import numpy as np

# 正确用法,传递了一个列表对象
a = np.array([1, 2, 3, 4])
print(a)  # 输出: [1 2 3 4]

创建数组(2)

NumPy 可以将嵌套的序列转换为多维数组。具体来说:

【序列的序列(如列表的列表、列表的元组、元组的列表等)将被转换为二维数组。
【序列的序列的序列将被转换为三维数组。
【更深层次的嵌套将被转换为更高维度的数组。
示例:

import numpy as np

b = np.array([(1.5, 2, 3), (4, 5, 6)])
print(b)
# 输出: 
# [[1.5 2.  3. ]
#  [4.  5.  6. ]]

函数zeros创建一个全为零的数组;
函数 ones创建一个全为 1 的数组;
函数empty 创建一个初始内容随机且取决于内存状态的数组。
默认情况下,创建的数组的 dtype 为 float64,但可以通过关键字参数指定dtype。

2、np.arange 函数(用于生成数值序列的函数)

np.arange(start, stop, step) 是 NumPy 提供的一个函数,用于生成一个一维数组,其元素是按照指定的步长从起始值到终止值的连续整数。
然而,当使用浮点数作为步长时,由于浮点数的精度问题,生成的元素数量可能无法准确预测。
这是因为浮点数在计算机中无法精确表示,从而导致累积误差。
它的基本用法如下:

import numpy as np

# 生成一个从0到14的整数数组
array = np.arange(15)
print(array)  # 输出: [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14]

3、np.linspace函数(用于生成数值序列的函数)

np.linspace(start, stop, num) 用于生成从 start 到 stop(包括 stop)的 num 个等间隔的数,接收元素数量作为参数,不受浮点精度问题的影响。

import numpy as np

# 生成从0到2的9个等间隔的数
b = np.linspace(0, 2, 9)
print(b)
# 输出: [0.   0.25 0.5  0.75 1.   1.25 1.5  1.75 2.  ]

4、ndarray.dtype 和 ndarray.dtype.name属性

  • b.dtype 返回的是一个 numpy.dtype 对象,它是 NumPy 用来描述数组数据类型的对象
    这个对象包含了关于数据类型的多种信息,比如数据类型的名称、大小、是否有符号等。
  • b.dtype.name 返回的是 dtype 对象的名称作为字符串。这个字符串表示数据类型的名称,通常是简洁的、易于阅读的名称。

示例 1: 数据类型对象:

import numpy as np

b = np.array([1, 2, 3], dtype=np.int64)

print(type(b.dtype))  # 输出: <class 'numpy.dtype'>
print(b.dtype)        # 输出: int64
  • type(b.dtype) 显示 b.dtype 是 numpy.dtype 对象的实例。
  • b.dtype 的输出是 int64,表示数据类型是 64 位整数。

示例 2: 数据类型名称:

print(b.dtype.name)  # 输出: int64
  • b.dtype.name 直接返回 dtype 对象的名称,作为一个字符串 “int64”。

5、矩阵乘积

  • @ 运算符:用于 Python 3.5 及更高版本,语法简洁,专用于矩阵乘积。
  • np.dot() 函数:通用的矩阵和向量点积函数,也可以处理更复杂的多维数组点积。
  • numpy.ndarray.dot() 方法:数组对象的方法,与 np.dot() 函数功能相同,但通过数组对象调用。
import numpy as np

# 定义两个矩阵
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])

# 使用 @ 运算符计算矩阵乘积
C = A @ B
print(C)

# 使用 np.dot() 函数计算矩阵乘积
D = np.dot(A, B)
print(D)

# 使用 np.dot() 函数计算矩阵乘积
E = A.dot(B)
print(E)

"""
输出:
[[19 22]
 [43 50]]
"""

6、ravel方法、T 和 flat属性

ravel() 返回一个展开(flattened)的一维数组。

import numpy as np
rg = np.random.default_rng() # 创建随机数生成器实例
a = np.floor(10 * rg.random((3, 4)))
flattened = a.ravel()
print(flattened)
'''
array([3., 7., 3., 4., 1., 4., 2., 2., 7., 2., 4., 9.])

'''

T 属性返回数组的转置(transpose),即将数组的行和列互换。

transposed = a.T
print(transposed)
'''
[[9. 0. 7.]
 [1. 9. 3.]
 [6. 5. 6.]
 [1. 5. 2.]]
'''

flat 将数组视为一维数组进行迭代,

for element in A.flat:
    print(element)
'''
for 循环按顺序访问A中的每个元素,并将其打印出来:
1
2
3
4
'''

7、np.vstack 和 np.hstack函数

np.vstack(vertical stack):
vstack 沿第一个轴(行方向)竖直拼接数组(原数组的行会被一个接一个地放在新数组中,形成一个更长的数组),使得新数组的行数是原数组行数之和,列数保持不变,要求被连接的数组列数相同。
np.hstack(horizontal stack):
hstack 沿第二个轴(列方向)水平拼接数组(将数组在水平方向上连接起来,即把一个数组的列加到另一个数组的列旁边),使得新数组的列数是原数组列数之和,行数保持不变,要求被连接的数组行数相同。
示例:

import numpy as np

a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
result1 = np.vstack((a, b))
print(result1)
'''
[[1 2]
 [3 4]
 [5 6]
 [7 8]]
 
'''
result2 = np.hstack((a, b))
print(result2)
'''
[[1 2 5 6]
 [3 4 7 8]]
'''

类似地:
1、np.concatenate

np.concatenate((a, b), axis=0)  # 沿着第一个轴(行)连接
np.concatenate((a, b), axis=1)  # 沿着第二个轴(列)连接

示例 :
axis=0:沿着第一个轴(行方向)拼接,将 b 的行追加到 a 的行后面

import numpy as np

a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])

result = np.concatenate((a, b), axis=0)
print(result)
'''
[[1 2]
 [3 4]
 [5 6]
 [7 8]]
 
'''

axis=1:沿着第二个轴(列方向)拼接,将 b 的列追加到 a 的列后面

result = np.concatenate((a, b), axis=1)
print(result)
'''
[[1 2 5 6]
 [3 4 7 8]]
 
'''

2、np.stack
功能: 沿着指定的轴将多个数组堆叠起来,创建一个新的维度
要求: 参与堆叠的数组必须具有相同的形状。

np.stack((a, b), axis=0)  # 沿着第一个轴(创建一个新的维度)堆叠
np.stack((a, b), axis=1)  # 沿着第二个轴(创建一个新的维度)堆叠

示例:

import numpy as np

a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])

result = np.stack((a, b), axis=0)
print(result)
'''
 输出:
 [[[1 2]
   [3 4]]

  [[5 6]
   [7 8]]]
'''
  • axis=0 表示在第一个轴的位置插入新维度。
  • 原本是两个形状为 (2, 2) 的二维数组,堆叠后变成了一个形状为
    (2, 2, 2) 的三维数组。
  • 新维度的大小是 2,即原来的两个数组 a 和 b 形成了这个新维度的两个“切片”。
  • 结果是一个三维数组,其中第一个维度(深度维度)表示 a 和 b。
result = np.stack((a, b), axis=1)
print(result)
'''
 输出:
[[[1 2]   # 来自 `a` 的第一行
  [5 6]]  # 来自 `b` 的第一行

 [[3 4]   # 来自 `a` 的第二行
  [7 8]]] # 来自 `b` 的第二行
'''
  • axis=1 表示在第二个轴的位置插入新维度。
  • 原本的二维数组 a 和 b 被堆叠在这个新维度上,形成了一个新的三维数组,形状为 (2, 2, 2)。
  • 新维度的大小是 2,即将 a 和 b 作为第二个轴的两个“切片”。
  • 结果是一个三维数组,其中第二个维度(列维度)是原来 a 和 b 的拼接。

8、column_stack 函数

  • column_stack 函数将 1D 数组作为堆叠成一个 2D 数组。
  • 当输入是 2D 数组时,column_stack 的行为与 hstack 是等价的。

示例:
当输入是 1D 数组时,column_stack 会将这些 1D 数组转换为列向量,然后将这些列向量拼接成一个 2D 数组。

import numpy as np

a = np.array([1, 2, 3])
b = np.array([4, 5, 6])

result = np.column_stack((a, b))
print(result)
'''
[[1 4]
 [2 5]
 [3 6]]
 
'''

当输入是 2D 数组时,column_stack 和 hstack 的行为是一样的,都会在列方向上进行拼接。

a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])

result_column_stack = np.column_stack((a, b))
result_hstack = np.hstack((a, b))

print(result_column_stack)
print(result_hstack)
'''
[[1 2 5 6]
 [3 4 7 8]]
[[1 2 5 6]
 [3 4 7 8]]
'''

9、np.r_ 和 np.c_ 函数

np.r_ 用于沿行方向(即第一个轴)将数值堆叠成数组。
它支持使用冒号 : 来表示范围,并允许将不同的数值和范围组合在一起。

import numpy as np

result = np.r_[1:4, 0, 4]
print(result)
'''
[1 2 3 0 4]

'''

np.c_ 用于沿列方向(即第二个轴)将数值堆叠成数组。
它的工作方式与 np.r_ 类似,但用于创建列向量或在列方向上堆叠数组。

import numpy as np

result = np.c_[1:4, [0]*3, [4]*3]
print(result)
'''
[[1 0 4]
 [2 0 4]
 [3 0 4]]
'''

10、np.hsplit 函数

将一个数组按照给定的分割点列表或分割段数进行切割,并返回一个包含子数组的列表
语法:

numpy.hsplit(ary, indices_or_sections)
  • ary:需要分割的数组。
  • indices_or_sections:指定分割点或分割段数。如果是一个整数,则表示将数组均匀分割为几部分;如果是一个整数列表,则表示在指定的列之后进行分割。

示例:

将数组 a 水平分割为 3 部分:

import numpy as np

a = np.floor(10 * np.random.random((2, 12)))
print(a)
'''
[[3. 2. 1. 1. 0. 5. 4. 5. 8. 5. 7. 6.]
 [6. 7. 1. 7. 1. 0. 2. 2. 0. 7. 1. 4.]]
'''

result = np.hsplit(a, 3)
print(result)
'''
[array([[3., 2., 1., 1.],
       [6., 7., 1., 7.]]), array([[0., 5., 4., 5.],
       [1., 0., 2., 2.]]), array([[8., 5., 7., 6.],
       [0., 7., 1., 4.]])]
'''

在指定的列之后进行分割:

import numpy as np

a = np.floor(10 * np.random.random((2, 12)))
print(a)
'''
[[5. 0. 9. 8. 1. 3. 8. 7. 2. 9. 2. 2.]
 [7. 5. 7. 1. 0. 0. 8. 5. 2. 8. 2. 0.]]
'''

result = np.hsplit(a, (3, 4))
print(result)
'''
第三列和第四列之后分割
[array([[5., 0., 9.],
       [7., 5., 7.]]), array([[8.],
       [1.]]), array([[1., 3., 8., 7., 2., 9., 2., 2.],
       [0., 0., 8., 5., 2., 8., 2., 0.]])]
'''

11、数组各轴的求和

将列索引视为最后,将行索引视为倒数第二个。这可以推广到具有任意维数的数组。

2D数组

  • 轴 0 是数组的第一个维度,代表数组中的行。
    沿轴 0 的操作会作用于每一列。例如,沿轴 0 求和会对每一列的所有行进行求和。

操作一个二维矩阵时,“沿着”某个方向进行操作意味着对这个方向的每个元素集合(即每一行或每一列)进行操作。

  • 轴 1 是数组的第二个维度,代表数组中的列。
    沿轴 1 的操作会作用于每一行。例如,沿轴 1 求和会对每一行的所有列进行求和。
import numpy as np

a = np.array([[1, 2, 3],
              [4, 5, 6],
              [7, 8, 9]])

轴 0 (Axis 0): 沿着垂直方向(也就是行的方向)的轴
沿轴 0 进行求和时,对每一列的所有行进行求和,结果是一个包含每一列总和的一维数组。

sum_axis_0 = np.sum(a, axis=0)
print(sum_axis_0)
'''
[12 15 18]
每个元素是对应列的总和。例如,第一列的总和是 1 + 4 + 7 = 12
'''

轴 1 (Axis 1): 沿着水平方向(也就是列的方向)的轴
沿轴 1 进行求和时,对每一行的所有列进行求和,结果是一个包含每一行总和的一维数组。

sum_axis_1 = np.sum(a, axis=1)
print(sum_axis_1)
'''
[6 15 24]
每个元素是对应行的总和。例如,第一行的总和是 1 + 2 + 3 = 6
'''

3D数组
假设有一个形状为 (p, m, n) 的 3D 数组,其中 p 是矩阵的数量(第一个维度),m 是每个矩阵的行数(第二个维度),n 是每个矩阵的列数(第三个维度)。

轴 0:第一个维度,代表 p 个 m x n 矩阵。
轴 1:第二个维度,代表每个 m x n 矩阵中的行。
轴 2:第三个维度,代表每个 m x n 矩阵中的列。

import numpy as np

a = np.array([[[1, 2, 3, 4],
               [5, 6, 7, 8],
               [9, 10, 11, 12]],

              [[13, 14, 15, 16],
               [17, 18, 19, 20],
               [21, 22, 23, 24]]])
# 可以视为有两个 3x4 的矩阵

轴 0 (Axis 0):这是最外层的轴,也就是矩阵的维度。在这个轴上操作时,会对所有矩阵进行计算。

sum_axis_0 = np.sum(a, axis=0)
print(sum_axis_0)
'''
[[14 16 18 20]
 [22 24 26 28]
 [30 32 34 36]]
每个元素是所有矩阵中对应位置的总和。
例如,第一个矩阵和第二个矩阵对应位置 (0, 0) 的元素和是 1 + 13 = 14,
对应位置 (1, 2) 的元素和是 7 + 19 = 26。
'''

轴 1 (Axis 1): 求和:每个矩阵的列的总和
沿轴 1 求和意味着对每个矩阵的每一列进行求和,并返回一个新的数组,其中的每一行是对原矩阵的所有列的求和结果。

sum_axis_1 = np.sum(a, axis=1)
print(sum_axis_1)
'''
[[15 18 21 24]
 [51 54 57 60]]
每个元素是每个矩阵中对应行的总和。
例如,第一个矩阵第一列的和是 1 + 5 + 9 = 15
第二列的和是 2 + 6 + 10 = 18,
第二个矩阵第一列的和是 13 + 17 + 21 = 51
第二列的和是 14 + 18 + 22 = 54。
'''

轴 2 (Axis 2): 求和:每个矩阵的行的总和
沿轴 2 求和意味着对每个矩阵的每一行进行求和,并返回一个新的数组,其中的每一行是对原矩阵的所有行的求和结果。

sum_axis_2 = np.sum(a, axis=2)
print(sum_axis_2)
'''
[[10 26 42]
 [58 74 90]]
每个元素是每个矩阵中对应列的总和。
例如,第一个矩阵的第一行列和是 1 + 2 + 3 + 4 = 10,第二行列和是 5 + 6 + 7 + 8 = 26
第二个矩阵的和则是 13 + 14 + 15 + 16 = 58,17 + 18 + 19 + 20 = 74。
'''

12、数组元素求和:sum()方法

import numpy as np
a = np.array([1, 2, 3, 4])

b = a.sum()
print(b)
'''
10
'''

13、Generator.integers方法

基本用法:

Generator.integers(low, high=None, size=None, dtype=int, endpoint=False)
  • low:生成的随机整数的下界(包括在内)。
    high:生成的随机整数的上界(不包括在内),如果不指定,则默认从 0 到 low。
  • size:输出数组的形状。如果是单个整数,则生成相应长度的一维数组;如果是元组,则生成相应形状的多维数组。
  • dtype:输出数组的类型,默认为 int。
  • endpoint:如果设为 True,则生成的随机整数包括上界(即 high)。

示例:

import numpy as np

rng = np.random.default_rng()
array = rng.integers(0, 4, size=(2, 4))
print(array)
'''
[[1 1 2 3]
 [1 0 3 3]]
'''

14、np.flip()函数

用于沿指定轴翻转或反转数组的内容
翻转一维数组

import numpy as np

arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
reversed_arr = np.flip(arr)
print('Reversed Array: ', reversed_arr)
'''
Reversed Array:  [8 7 6 5 4 3 2 1]

'''

翻转二维数组

import numpy as np

arr_2d = np.array([[1, 2, 3, 4], 
                   [5, 6, 7, 8], 
                   [9, 10, 11, 12]])
# 翻转整个数组(即,所有行和所有列):
reversed_arr = np.flip(arr_2d)
print(reversed_arr)
'''
[[12 11 10  9]
 [ 8  7  6  5]
 [ 4  3  2  1]]
 
'''
# 仅沿行轴(即 axis=0)翻转数组:
reversed_arr_rows = np.flip(arr_2d, axis=0)
print(reversed_arr_rows)
'''
[[ 9 10 11 12]
 [ 5  6  7  8]
 [ 1  2  3  4]]
这里,数组的行顺序被反转,但每一行内部的元素顺序保持不变。
'''
# 仅沿列轴(即 axis=1)翻转数组:
reversed_arr_columns = np.flip(arr_2d, axis=1)
print(reversed_arr_columns)
'''
[[ 4  3  2  1]
 [ 8  7  6  5]
 [12 11 10  9]]
这里,数组的列顺序被反转,但每一列内部的元素顺序保持不变。
'''
# 翻转特定行,例如索引位置为1的行(即第二行):
arr_2d[1] = np.flip(arr_2d[1])
print(arr_2d)
'''
[[ 1  2  3  4]
 [ 8  7  6  5]
 [ 9 10 11 12]]
这里,仅第二行的元素顺序被反转。
'''
# 翻转特定列,例如索引位置为1的列(即第二列):
arr_2d[:, 1] = np.flip(arr_2d[:, 1])
print(arr_2d)
'''
[[ 1 10  3  4]
 [ 8  7  6  5]
 [ 9  2 11 12]]
这里,仅第二列的元素顺序被反转。
'''

总结

本文总结了 NumPy 库中入门级的一些常用函数和方法,帮助初学者掌握基本的数组和矩阵操作。

  • 33
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值