杰瑞科技汇

Python如何计算特征值?

Of course! Calculating eigenvalues is a fundamental task in linear algebra, and Python offers excellent tools for it. The most common and efficient way is by using the NumPy library.

Python如何计算特征值?-图1
(图片来源网络,侵删)

Here's a complete guide, starting from the basics and moving to more advanced concepts.

The Core Concept: What is an Eigenvalue?

Imagine a square matrix A and a non-zero vector v. If multiplying A by v only scales v by a scalar factor , then:

A @ v = λ * v

  • v is called an eigenvector.
  • (lambda) is the corresponding eigenvalue.

Essentially, the eigenvector v is a special direction that doesn't change when the linear transformation represented by A is applied; it only gets stretched or shrunk by the eigenvalue .

Python如何计算特征值?-图2
(图片来源网络,侵删)

The Easiest Way: Using NumPy

NumPy's linalg (linear algebra) module provides the eigvals function to compute eigenvalues and eig to compute both eigenvalues and eigenvectors.

Installation

If you don't have NumPy installed, open your terminal or command prompt and run:

pip install numpy

Example 1: Finding Eigenvalues of a 2x2 Matrix

Let's find the eigenvalues for the matrix:

A = [[4, 1],
     [2, 3]]
import numpy as np
# Define the matrix as a NumPy array
A = np.array([[4, 1],
              [2, 3]])
# Calculate eigenvalues
# np.linalg.eigvals returns a 1D array of eigenvalues
eigenvalues = np.linalg.eigvals(A)
print(f"The matrix A is:\n{A}\n")
print(f"The eigenvalues are: {eigenvalues}")

Output:

Python如何计算特征值?-图3
(图片来源网络,侵删)
The matrix A is:
[[4 1]
 [2 3]]
The eigenvalues are: [5. 2.]

This means the eigenvalues are 5 and 2.

Example 2: Finding Eigenvalues AND Eigenvectors

Often, you need both. For this, you use np.linalg.eig. It returns a tuple:

  1. A 1D array of eigenvalues.
  2. A 2D array where each column is the corresponding eigenvector.
import numpy as np
A = np.array([[4, 1],
              [2, 3]])
# Calculate both eigenvalues and eigenvectors
# The result is a tuple: (eigenvalues, eigenvectors)
eigenvalues, eigenvectors = np.linalg.eig(A)
print(f"The matrix A is:\n{A}\n")
print(f"The eigenvalues are: {eigenvalues}\n")
print("The eigenvectors are:\n", eigenvectors)
# Let's verify the result for the first eigenvalue/eigenvector pair
# A @ v1 should equal lambda1 * v1
v1 = eigenvectors[:, 0]  # First column
lambda1 = eigenvalues[0]
print("\n--- Verification ---")
print(f"A @ v1 = \n{A @ v1}")
print(f"lambda1 * v1 = \n{lambda1 * v1}")

Output:

The matrix A is:
[[4 1]
 [2 3]]
The eigenvalues are: [5. 2.]
The eigenvectors are:
 [[ 0.70710678 -0.4472136 ]
 [ 0.70710678  0.89442719]]
--- Verification ---
A @ v1 =
[3.53553391 3.53553391]
lambda1 * v1 =
[3.53553391 3.53553391]

The verification shows that A @ v1 is indeed equal to 5 * v1 (within floating-point precision).


Key Considerations and Advanced Topics

A. Complex Eigenvalues

Not all matrices have real eigenvalues. If a matrix has complex eigenvalues, NumPy will return them as complex numbers.

import numpy as np
# A rotation matrix will have complex eigenvalues
# B = [[cos(θ), -sin(θ)],
#      [sin(θ),  cos(θ)]]
theta = np.pi / 4  # 45 degrees
B = np.array([[np.cos(theta), -np.sin(theta)],
              [np.sin(theta), np.cos(theta)]])
eigenvalues, eigenvectors = np.linalg.eig(B)
print(f"The matrix B is:\n{B}\n")
print(f"The eigenvalues are: {eigenvalues}") # Note the 'j' indicating a complex number

Output:

The matrix B is:
[[ 0.70710678 -0.70710678]
 [ 0.70710678  0.70710678]]
The eigenvalues are: [0.70710678+0.70710678j 0.70710678-0.70710678j]

B. Specialized Matrices: Symmetric Matrices

For symmetric or Hermitian matrices, all eigenvalues are guaranteed to be real. Furthermore, NumPy provides a specialized, more efficient function for them: np.linalg.eigh (the 'h' stands for Hermitian).

  • np.linalg.eig: General-purpose, works for any square matrix. Can return complex numbers.
  • np.linalg.eigh: Optimized for symmetric/Hermitian matrices. Is faster and more numerically stable. Always returns real eigenvalues.
import numpy as np
# A symmetric matrix
C = np.array([[2, 1, 0],
              [1, 2, 1],
              [0, 1, 2]])
# Using the general function
eigvals_general, eigvecs_general = np.linalg.eig(C)
# Using the specialized function for symmetric matrices
eigvals_sym, eigvecs_sym = np.linalg.eigh(C)
print("--- General Eig ---")
print(f"Eigenvalues: {eigvals_general}")
print(f"Are all eigenvalues real? {np.all(np.isreal(eigvals_general))}")
print("\n--- Symmetric Eigh ---")
print(f"Eigenvalues: {eigvals_sym}")
print(f"Are all eigenvalues real? {np.all(np.isreal(eigvals_sym))}")

Output:

--- General Eig ---
Eigenvalues: [3.41421356 1.         0.58578644]
Are all eigenvalues real? True
--- Symmetric Eigh ---
Eigenvalues: [0.58578644 1.         3.41421356]
Are all eigenvalues real? True

Note that eigh returns the eigenvalues sorted in ascending order by default, while eig does not.

C. Eigenvalues of Large Matrices

For very large, sparse matrices (where most elements are zero), calculating all eigenvalues is extremely memory-intensive and slow. In these cases, you typically only want a few of the largest or smallest eigenvalues.

For this, you should use SciPy. The scipy.sparse.linalg module has powerful iterative methods.

Installation:

pip install scipy

Example: Finding the Largest Eigenvalue (Power Iteration)

import numpy as np
from scipy.sparse.linalg import eigs
# Create a large, sparse matrix (e.g., 1000x1000)
# For this example, we'll make a dense one and convert it to sparse format
n = 1000
A_large = np.random.rand(n, n)
# Make it symmetric to ensure real eigenvalues
A_large = (A_large + A_large.T) / 2 
# Convert to a sparse matrix format (CSC is efficient for many operations)
from scipy.sparse import csc_matrix
A_sparse = csc_matrix(A_large)
# We want to find the 5 largest magnitude eigenvalues
# k is the number of eigenvalues to find
# which='LM' means "Largest Magnitude"
try:
    # eigs can sometimes fail to converge, so a try-except block is good practice
    eigenvalues_large, eigenvectors_large = eigs(A_sparse, k=5, which='LM')
    print(f"The 5 largest eigenvalues are:\n{eigenvalues_large}")
except ArpackNoConvergence as e:
    print(f"ARPACK did not converge. Partial results: {e.eigenvalues}")

This approach is vastly more efficient than np.linalg.eig for matrices with millions of rows and columns.


Summary: Which Function to Use?

Your Goal Recommended Function Why?
Quick eigenvalues for any small matrix np.linalg.eigvals() Simple, direct, and fast for small to medium-sized matrices.
Eigenvalues and eigenvectors for any matrix np.linalg.eig() The general-purpose workhorse.
Matrix is symmetric/Hermitian np.linalg.eigh() Much faster and more stable. Guarantees real eigenvalues and sorts them.
Large, sparse matrix; only a few eigenvalues scipy.sparse.linalg.eigs() The only feasible option. Uses iterative methods to avoid the massive memory and computation cost.
分享:
扫描分享到社交APP
上一篇
下一篇