第十二章:NumPy 应用案例 (可选,根据实践性调整)


文档摘要

第十二章:NumPy 应用案例 (可选,根据实践性调整) 第十二章:NumPy 应用案例 NumPy 作为 Python 中科学计算的核心库,在数据分析、机器学习、图像处理等领域有着广泛的应用。本章将通过几个实际案例,展示 NumPy 如何解决实际问题,并深入探讨其背后的原理和技巧。 1. 图像处理:图像灰度化和直方图均衡化 图像可以看作是一个多维数组,NumPy 擅长处理这类数据。我们以图像灰度化和直方图均衡化为例,展示 NumPy 在图像处理中的应用。 1.1 图像灰度化 彩色图像通常由 RGB 三个通道组成,每个通道的值代表红、绿、蓝的强度。灰度化是将彩色图像转换为灰度图像的过程,灰度图像只有一个通道,每个像素的值代表灰度值。

第十二章:NumPy 应用案例 (可选,根据实践性调整)

第十二章:NumPy 应用案例

NumPy 作为 Python 中科学计算的核心库,在数据分析、机器学习、图像处理等领域有着广泛的应用。本章将通过几个实际案例,展示 NumPy 如何解决实际问题,并深入探讨其背后的原理和技巧。

1. 图像处理:图像灰度化和直方图均衡化

图像可以看作是一个多维数组,NumPy 擅长处理这类数据。我们以图像灰度化和直方图均衡化为例,展示 NumPy 在图像处理中的应用。

1.1 图像灰度化

彩色图像通常由 RGB 三个通道组成,每个通道的值代表红、绿、蓝的强度。灰度化是将彩色图像转换为灰度图像的过程,灰度图像只有一个通道,每个像素的值代表灰度值。

代码实践:

import numpy as np import matplotlib.pyplot as plt from PIL import Image # 读取图像 img = Image.open('image.jpg') # 替换成你的图像路径 img_array = np.array(img) # 灰度化 def grayscale(img_array): # 使用加权平均法进行灰度化 gray_array = 0.299 * img_array[:, :, 0] + 0.587 * img_array[:, :, 1] + 0.114 * img_array[:, :, 2] return gray_array.astype(np.uint8) gray_img = grayscale(img_array) # 显示图像 plt.figure(figsize=(10, 5)) plt.subplot(1, 2, 1) plt.imshow(img_array) plt.title('Original Image') plt.axis('off') plt.subplot(1, 2, 2) plt.imshow(gray_img, cmap='gray') plt.title('Grayscale Image') plt.axis('off') plt.show()

内容详解:

  • Image.open()np.array(): 首先使用 PIL 库的 Image.open() 函数读取图像,然后使用 NumPy 的 np.array() 函数将图像转换为 NumPy 数组。

  • 灰度化公式: 使用加权平均法进行灰度化,公式为 Gray = 0.299 * R + 0.587 * G + 0.114 * B。这个公式考虑了人眼对不同颜色的敏感度。

  • 数据类型转换: gray_array.astype(np.uint8) 将灰度值转换为 uint8 类型,这是图像常用的数据类型,表示 0-255 之间的整数。

  • plt.imshow(): 使用 matplotlib.pyplot 库的 imshow() 函数显示图像。cmap='gray' 指定使用灰度颜色映射。

1.2 直方图均衡化

直方图均衡化是一种增强图像对比度的技术,通过调整图像的像素值分布,使其更均匀地分布在整个灰度范围内。

代码实践:

import numpy as np import matplotlib.pyplot as plt from PIL import Image # 读取图像并灰度化 (假设已经完成了灰度化) img = Image.open('image.jpg').convert('L') # 直接读取为灰度图像 img_array = np.array(img) def histogram_equalization(img_array): # 计算直方图 histogram, bins = np.histogram(img_array.flatten(), 256, [0, 256]) # 计算累积分布函数 (CDF) cdf = histogram.cumsum() # 归一化 CDF cdf_normalized = cdf * float(histogram.max()) / cdf.max() # 创建映射表 cdf_m = np.ma.masked_equal(cdf, 0) cdf_m = (cdf_m - cdf_m.min()) * 255 / (cdf_m.max() - cdf_m.min()) cdf = np.ma.filled(cdf_m, 0).astype('uint8') # 应用映射表 img_new = cdf[img_array] return img_new equalized_img = histogram_equalization(img_array) # 显示图像和直方图 plt.figure(figsize=(15, 5)) plt.subplot(1, 3, 1) plt.imshow(img_array, cmap='gray') plt.title('Original Grayscale Image') plt.axis('off') plt.subplot(1, 3, 2) plt.imshow(equalized_img, cmap='gray') plt.title('Equalized Image') plt.axis('off') plt.subplot(1, 3, 3) plt.hist(img_array.flatten(), 256, [0, 256], color = 'r', alpha = 0.5, label='Original') plt.hist(equalized_img.flatten(), 256, [0, 256], color = 'b', alpha = 0.5, label='Equalized') plt.legend(loc='upper right') plt.title('Histograms') plt.show()

内容详解:

  • np.histogram(): 计算图像的直方图,img_array.flatten() 将图像数组展平为一维数组,256 表示灰度级的数量,[0, 256] 表示灰度值的范围。

  • cumsum(): 计算累积分布函数 (CDF),CDF 表示小于等于某个灰度值的像素数量的比例。

  • 映射表: 根据 CDF 创建映射表,将原始灰度值映射到新的灰度值,使得像素值分布更均匀。

  • np.ma.masked_equal()np.ma.filled(): 处理 CDF 中可能存在的 0 值,避免除以 0 的错误。

  • cdf[img_array]: 使用映射表对图像进行变换,将原始图像的每个像素值替换为映射后的值。

2. 数据分析:股票数据分析

NumPy 可以用于存储和处理股票数据,并进行一些简单的分析,例如计算平均价格、最大价格和最小价格。

代码实践:

import numpy as np # 模拟股票数据 (日期, 开盘价, 最高价, 最低价, 收盘价, 成交量) stock_data = np.array([ ['2023-10-26', 145.5, 147.2, 144.8, 146.9, 10000], ['2023-10-27', 146.9, 148.1, 146.2, 147.5, 12000], ['2023-10-28', 147.5, 149.0, 147.0, 148.5, 15000], ['2023-10-29', 148.5, 149.5, 148.0, 149.2, 13000], ['2023-10-30', 149.2, 150.0, 148.8, 149.8, 14000] ]) # 将价格和成交量转换为数值类型 prices = stock_data[:, 1:5].astype(float) volume = stock_data[:, 5].astype(float) # 计算平均价格 average_prices = np.mean(prices, axis=0) print("平均开盘价, 最高价, 最低价, 收盘价:", average_prices) # 计算最大价格 max_price = np.max(prices) print("最高价格:", max_price) # 计算最小价格 min_price = np.min(prices) print("最低价格:", min_price) # 计算总成交量 total_volume = np.sum(volume) print("总成交量:", total_volume) # 找到收盘价最高的日期 closing_prices = prices[:, 3] highest_closing_price_index = np.argmax(closing_prices) highest_closing_price_date = stock_data[highest_closing_price_index, 0] print("收盘价最高的日期:", highest_closing_price_date)

内容详解:

  • 数据存储: 使用 NumPy 数组存储股票数据,每一行代表一天的数据,每一列代表不同的属性。

  • 数据类型转换: 使用 astype(float) 将价格和成交量转换为数值类型,方便进行计算。

  • np.mean(): 计算平均价格,axis=0 表示沿着列的方向计算平均值。

  • np.max()np.min(): 计算最大价格和最小价格。

  • np.sum(): 计算总成交量。

  • np.argmax(): 找到收盘价最高的日期的索引。

3. 机器学习:简单的线性回归

NumPy 可以用于实现一些简单的机器学习算法,例如线性回归。

代码实践:

import numpy as np import matplotlib.pyplot as plt # 生成模拟数据 X = np.array([1, 2, 3, 4, 5]) y = np.array([2, 4, 5, 4, 5]) # 添加偏置项 X = np.vstack((np.ones(len(X)), X)).T # 使用最小二乘法求解线性回归 def linear_regression(X, y): # 计算权重 w = np.linalg.inv(X.T @ X) @ X.T @ y return w # 训练模型 w = linear_regression(X, y) # 预测 def predict(X, w): return X @ w y_pred = predict(X, w) # 打印权重 print("权重:", w) # 绘制结果 plt.scatter(X[:, 1], y, label='Actual') plt.plot(X[:, 1], y_pred, color='red', label='Predicted') plt.xlabel('X') plt.ylabel('y') plt.legend() plt.show()

内容详解:

  • 模拟数据: 生成一些模拟数据,用于训练线性回归模型。

  • 添加偏置项: 在线性回归模型中,需要添加一个偏置项,可以使用 np.ones() 函数生成一个全 1 向量,然后使用 np.vstack() 函数将其添加到 X 矩阵中。

  • 最小二乘法: 使用最小二乘法求解线性回归模型的权重,公式为 w = (X^T X)^{-1} X^T y

  • np.linalg.inv(): 计算矩阵的逆。

  • 预测: 使用训练好的模型进行预测,公式为 y_pred = Xw

4. 模拟:随机漫步

NumPy 可以用于模拟随机过程,例如随机漫步。

代码实践:

import numpy as np import matplotlib.pyplot as plt # 设置随机种子 np.random.seed(0) # 模拟随机漫步 def random_walk(n_steps): # 生成随机步长 (-1 或 1) steps = np.random.choice([-1, 1], size=n_steps) # 计算累积步长 walk = np.cumsum(steps) return walk # 模拟 1000 步的随机漫步 walk = random_walk(1000) # 绘制随机漫步轨迹 plt.plot(walk) plt.xlabel('Steps') plt.ylabel('Position') plt.title('Random Walk') plt.show() # 统计信息 print("最大位置:", walk.max()) print("最小位置:", walk.min()) print("首次到达 10 的步数:", (np.abs(walk) >= 10).argmax())

内容详解:

  • np.random.choice():[-1, 1] 中随机选择步长,size=n_steps 表示生成 n_steps 个随机步长。

  • np.cumsum(): 计算累积步长,表示每一步的位置。

  • (np.abs(walk) >= 10).argmax(): 找到首次到达绝对值大于等于 10 的位置的索引。

5. 性能优化:NumPy 矢量化

NumPy 的矢量化操作可以显著提高代码的性能。通过避免显式循环,利用 NumPy 的底层 C 代码进行高效计算。

代码实践:

import numpy as np import time # 使用循环计算平方和 def sum_of_squares_loop(arr): result = 0 for x in arr: result += x**2 return result # 使用 NumPy 矢量化计算平方和 def sum_of_squares_numpy(arr): return np.sum(arr**2) # 创建一个大的 NumPy 数组 arr = np.random.rand(1000000) # 比较两种方法的性能 start_time = time.time() result_loop = sum_of_squares_loop(arr) end_time = time.time() loop_time = end_time - start_time start_time = time.time() result_numpy = sum_of_squares_numpy(arr) end_time = time.time() numpy_time = end_time - start_time print("循环计算时间:", loop_time) print("NumPy 矢量化计算时间:", numpy_time) print("NumPy 速度提升:", loop_time / numpy_time, "倍")

内容详解:

  • 矢量化操作: arr**2np.sum() 都是矢量化操作,它们可以同时对数组中的所有元素进行计算,而不需要显式循环。

  • 性能提升: NumPy 的矢量化操作通常比显式循环快很多,因为 NumPy 的底层代码是用 C 语言编写的,并且经过了高度优化。

结论

本章通过几个实际案例,展示了 NumPy 在图像处理、数据分析、机器学习和模拟等领域的应用。NumPy 的强大功能和高效性能使其成为科学计算的必备工具。掌握 NumPy 的使用技巧,可以有效地解决实际问题,并提高代码的效率。

Graph TD 图示:

这个图示简单地展示了本章涵盖的几个应用案例,以及每个案例的具体内容。你可以根据需要添加更多的细节,例如每个案例中使用到的 NumPy 函数和技巧。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U