Skip to content

SciPy - 基本功能

SciPy - 基本功能与 NumPy 的互操作性

Section titled “SciPy - 基本功能与 NumPy 的互操作性”

SciPy 基本上是建立在 NumPy 之上的。所有 NumPy 函数都可以通过 SciPy 命名空间访问(例如,scipy.array 就是 numpy.array)。因此,导入 SciPy 通常无需显式导入 NumPy 来进行数组操作,不过通常习惯于导入 NumPy 为 np 以提高代码清晰度。

NumPy 的核心数据结构,也是 SciPy 中广泛使用的,是 ndarray(N维数组)。它是一个元素表,通常是数字,所有元素都具有相同的数据类型,通过一个非负整数的元组进行索引。在 NumPy 中,维度称为 轴(axes),轴的数量称为 数组的秩(rank)。

在深入研究 SciPy 的模块之前,理解 NumPy 数组的创建和操作至关重要,因为大多数 SciPy 函数都期望以 ndarray 对象作为输入,并经常返回 ndarray 作为输出。

数组,可以是向量(1D 数组)或矩阵(2D 数组),可以通过几种方式创建。

创建数组最直接的方法是使用 numpy.array() 从 Python 列表或元组创建:

import numpy as np
# Creating a 1D array (vector)
python_list = [1, 2, 3, 4, 5]
arr_1d = np.array(python_list)
print("1D Array (Vector):")
print(arr_1d)
# Creating a 2D array (matrix)
python_nested_list = [[1, 2], [3, 4], [5, 6]]
arr_2d = np.array(python_nested_list)
print("\n2D Array (Matrix):")
print(arr_2d)

输出:

1D Array (Vector):
[1 2 3 4 5]
2D Array (Matrix):
[[1 2]
[3 4]
[5 6]]

NumPy 提供了几个函数来从头创建具有预定义内容的数组。

zeros(shape, dtype=float) 函数创建填充零的数组,ones(shape, dtype=float) 创建填充一的数组。shape 是一个指定维度的元组。

import numpy as np
zeros_arr = np.zeros((2, 3)) # A 2x3 array of zeros
print("Zeros Array (default dtype float64):")
print(zeros_arr)
ones_arr = np.ones((3, 2), dtype=int) # A 3x2 array of ones with integer type
print("\nOnes Array (dtype int):")
print(ones_arr)

输出:

Zeros Array (default dtype float64):
[[0. 0. 0.]
[0. 0. 0.]]
Ones Array (dtype int):
[[1 1]
[1 1]
[1 1]]

arange([start,] stop[, step,], dtype=None) 函数创建具有规则递增值的数组,类似于 Python 的 range(),但返回一个 ndarray。

import numpy as np
arr_seq = np.arange(7) # 0 to 6
print("Sequence from 0 to 6:")
print(arr_seq)
arr_step = np.arange(2, 10, 2) # Start at 2, end before 10, step by 2
print("\nSequence with a step:")
print(arr_step)

输出:

Sequence from 0 to 6:
[0 1 2 3 4 5 6]
Sequence with a step:
[2 4 6 8]

您可以使用 dtype 参数显式定义数组元素的数据类型。常见的类型包括 int、float、np.float32、np.int64 等。在许多 NumPy 上下文中,使用 float 通常等同于 np.float64(双精度)。

import numpy as np
arr_float = np.arange(5, dtype=float) # Default float is usually np.float64
print("Array with float dtype:")
print(arr_float)
print(f"Data Type: {arr_float.dtype}")
arr_int32 = np.array([10, 20, 30], dtype=np.int32)
print("\nArray with int32 dtype:")
print(arr_int32)
print(f"Data Type: {arr_int32.dtype}")

输出:

Array with float dtype:
[0. 1. 2. 3. 4.]
Data Type: float64
Array with int32 dtype:
[10 20 30]
Data Type: int32

linspace(start, stop, num=50, endpoint=True, dtype=None) 函数创建具有指定数量 (num) 元素的数组,这些元素在指定的区间 [start, stop] 内均匀分布。

import numpy as np
# Create 6 evenly spaced numbers between 1.0 and 4.0 (inclusive)
arr_spaced = np.linspace(1.0, 4.0, num=6)
print("Evenly spaced numbers:")
print(arr_spaced)

输出:

Evenly spaced numbers:
[1. 1.6 2.2 2.8 3.4 4. ]

NumPy 还有一个 matrix 类 (np.matrix)。虽然 np.matrix 对象严格来说是二维的,并且为矩阵乘法 (*) 和幂运算 (**) 提供了方便的运算符重载,但对于新代码,通常建议使用 np.ndarray 进行所有数组操作。ndarray 可以是 N 维的,矩阵乘法使用 @ 运算符或 np.matmul() 函数执行。

使用 np.matrix 的示例(在现代代码中较少见):

import numpy as np
mat = np.matrix('1 2; 3 4') # Create a matrix from a string
print("NumPy Matrix:")
print(mat)
# Matrix multiplication with *
mat_squared = mat * mat
print("\nMatrix squared (using *):")
print(mat_squared)

输出:

NumPy Matrix:
[[1 2]
[3 4]]
Matrix squared (using *):
[[ 7 10]
[15 22]]

使用 np.ndarray 的等效代码(更推荐):

import numpy as np
arr = np.array([[1, 2], [3, 4]])
print("NumPy ndarray:")
print(arr)
# Matrix multiplication with @
arr_squared = arr @ arr
print("\nArray squared (using @):")
print(arr_squared)

输出:

NumPy ndarray:
[[1 2]
[3 4]]
Array squared (using @):
[[ 7 10]
[15 22]]

转置 (Transpose) 和共轭转置 (Conjugate Transpose)

Section titled “转置 (Transpose) 和共轭转置 (Conjugate Transpose)”

对于 ndarray(或 np.matrix):

  • .T 属性:返回数组的转置。
  • .conj().T 或 .H(对于 np.matrix):返回共轭转置(Hermitian transpose)。对于实数数组,转置和共轭转置是相同的。
import numpy as np
# Real array
real_arr = np.array([[1, 2], [3, 4]])
print("Original Real Array:")
print(real_arr)
print("\nTranspose of Real Array (.T):")
print(real_arr.T)
# Complex array
complex_arr = np.array([[1+1j, 2+2j], [3+3j, 4+4j]])
print("\nOriginal Complex Array:")
print(complex_arr)
print("\nTranspose of Complex Array (.T):")
print(complex_arr.T)
print("\nConjugate Transpose of Complex Array (.conj().T):")
print(complex_arr.conj().T)

输出:

Original Real Array:
[[1 2]
[3 4]]
Transpose of Real Array (.T):
[[1 3]
[2 4]]
Original Complex Array:
[[1.+1.j 2.+2.j]
[3.+3.j 4.+4.j]]
Transpose of Complex Array (.T):
[[1.+1.j 3.+3.j]
[2.+2.j 4.+4.j]]
Conjugate Transpose of Complex Array (.conj().T):
[[1.-1.j 3.-3.j]
[2.-2.j 4.-4.j]]

SciPy 的模块广泛使用这些 NumPy 数组特性。因此,扎实掌握 NumPy 是有效使用 SciPy 进行科学和技术计算的第一步。