【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】 1.3 广播机制:维度自动扩展的黑魔法

在这里插入图片描述

1.3 《广播机制:维度自动扩展的黑魔法》

前言

NumPy 的广播机制是 Python 科学计算中最强大的工具之一,它允许不同形状的数组进行运算,而无需显式地扩展数组的维度。这一机制在实际编程中非常有用,但初学者往往对其感到困惑。在这篇文章中,我们将深入解析 NumPy 的广播机制,探讨其规则、原理和应用场景,并通过实验验证其性能和内存优化。

1.3.1 广播规则的决策树流程图

NumPy 的广播规则可以通过一个决策树流程图来直观地理解。以下是广播规则的决策树流程图:

开始
数组 A 和 B 的形状是否相同?
直接进行运算
数组 A 和 B 的维度是否可以扩展?
扩展维度,进行运算
数组 A 和 B 的形状是否可以调整?
调整形状,进行运算
引发 ValueError
输入数组 A 和 B
A 和 B 的形状
A 和 B 的维度
A 和 B 的步长
形状匹配验证
结束
1.3.2 从标量到高维数组的6种广播场景

广播机制可以根据输入数组的形状和维度分为多种场景。以下是常见的 6 种广播场景,并附上代码示例和注释。

场景1:标量与一维数组

import numpy as np# 创建一个标量
scalar = 2
# 创建一个一维数组
array1 = np.array([1, 2, 3])# 进行广播运算
result1 = array1 + scalar
print("标量与一维数组的广播结果:")
print(result1)

注释:

# 导入 NumPy 库,并将其别名为 np
import numpy as np# 创建一个标量
# 标量是一个单独的数值
scalar = 2# 创建一个一维数组
# np.array 是 NumPy 中用于创建数组的函数
array1 = np.array([1, 2, 3])# 进行广播运算
# 广播机制将标量扩展为与一维数组相同形状的数组
# 然后进行逐元素运算
result1 = array1 + scalar
print("标量与一维数组的广播结果:")  # 打印结果
print(result1)

场景2:一维数组与二维数组

import numpy as np# 创建一个一维数组
array1 = np.array([1, 2, 3])
# 创建一个二维数组
array2 = np.array([[1, 2, 3], [4, 5, 6]])# 进行广播运算
result2 = array1 + array2
print("一维数组与二维数组的广播结果:")
print(result2)

注释:

# 导入 NumPy 库,并将其别名为 np
import numpy as np# 创建一个一维数组
array1 = np.array([1, 2, 3])# 创建一个二维数组
array2 = np.array([[1, 2, 3], [4, 5, 6]])# 进行广播运算
# 广播机制将一维数组扩展为与二维数组相同形状的数组
# 然后进行逐元素运算
result2 = array1 + array2
print("一维数组与二维数组的广播结果:")  # 打印结果
print(result2)

场景3:标量与二维数组

import numpy as np# 创建一个标量
scalar = 2
# 创建一个二维数组
array2 = np.array([[1, 2, 3], [4, 5, 6]])# 进行广播运算
result3 = array2 + scalar
print("标量与二维数组的广播结果:")
print(result3)

注释:

# 导入 NumPy 库,并将其别名为 np
import numpy as np# 创建一个标量
scalar = 2# 创建一个二维数组
array2 = np.array([[1, 2, 3], [4, 5, 6]])# 进行广播运算
# 广播机制将标量扩展为与二维数组相同形状的数组
# 然后进行逐元素运算
result3 = array2 + scalar
print("标量与二维数组的广播结果:")  # 打印结果
print(result3)

场景4:一维数组与三维数组

import numpy as np# 创建一个一维数组
array1 = np.array([1, 2, 3])
# 创建一个三维数组
array3 = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])# 进行广播运算
result4 = array1 + array3
print("一维数组与三维数组的广播结果:")
print(result4)

注释:

# 导入 NumPy 库,并将其别名为 np
import numpy as np# 创建一个一维数组
array1 = np.array([1, 2, 3])# 创建一个三维数组
array3 = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])# 进行广播运算
# 广播机制将一维数组扩展为与三维数组相同形状的数组
# 然后进行逐元素运算
result4 = array1 + array3
print("一维数组与三维数组的广播结果:")  # 打印结果
print(result4)

场景5:二维数组与三维数组

import numpy as np# 创建一个二维数组
array2 = np.array([[1, 2, 3], [4, 5, 6]])
# 创建一个三维数组
array3 = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])# 进行广播运算
result5 = array2 + array3
print("二维数组与三维数组的广播结果:")
print(result5)

注释:

# 导入 NumPy 库,并将其别名为 np
import numpy as np# 创建一个二维数组
array2 = np.array([[1, 2, 3], [4, 5, 6]])# 创建一个三维数组
array3 = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])# 进行广播运算
# 广播机制将二维数组扩展为与三维数组相同形状的数组
# 然后进行逐元素运算
result5 = array2 + array3
print("二维数组与三维数组的广播结果:")  # 打印结果
print(result5)

场景6:不兼容形状的处理

import numpy as np# 创建一个 3x3 的数组
array3 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])# 创建一个可以广播的一维数组
array1 = np.array([1, 2, 3])
# 创建一个不可以广播的一维数组
array2 = np.array([1, 2])# 正确的广播运算
result1 = array3 + array1
print("正确的广播运算结果:")
print(result1)# 错误的广播运算
try:result2 = array3 + array2
except ValueError as e:print("错误的广播运算结果:")print(e)# 使用 np.broadcast_arrays 检查广播后的形状
broadcasted_arrays = np.broadcast_arrays(array3, array1)
print("广播后的数组形状:")
for b in broadcasted_arrays:print(b.shape)# 使用 np.broadcast_to 显式广播
explicitly_broadcasted = np.broadcast_to(array1, (3, 3))
print("显式广播后的数组:")
print(explicitly_broadcasted)

注释:

# 导入 NumPy 库,并将其别名为 np
import numpy as np# 创建一个 3x3 的数组
array3 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])# 创建一个可以广播的一维数组
array1 = np.array([1, 2, 3])
# 创建一个不可以广播的一维数组
array2 = np.array([1, 2])# 正确的广播运算
# array1 的形状为 (3,),可以广播为 (3, 3)
result1 = array3 + array1
print("正确的广播运算结果:")  # 打印结果
print(result1)# 错误的广播运算
# array2 的形状为 (2,),不能广播为 (3, 3)
try:result2 = array3 + array2
except ValueError as e:print("错误的广播运算结果:")  # 打印错误信息print(e)# 使用 np.broadcast_arrays 检查广播后的形状
# np.broadcast_arrays 是 NumPy 中用于返回广播后的数组的函数
# 传入两个数组作为参数
broadcasted_arrays = np.broadcast_arrays(array3, array1)
print("广播后的数组形状:")  # 打印广播后的数组形状
for b in broadcasted_arrays:print(b.shape)# 使用 np.broadcast_to 显式广播
# np.broadcast_to 是 NumPy 中用于显式将数组广播到指定形状的函数
# 传入数组和目标形状作为参数
explicitly_broadcasted = np.broadcast_to(array1, (3, 3))
print("显式广播后的数组:")  # 打印显式广播后的数组
print(explicitly_broadcasted)
1.3.3 广播时的内存优化原理(避免实际复制)

广播机制的一个重要优点是它可以避免实际的数据复制,从而节省内存。我们将通过一个实验来验证这一原理。

import numpy as np
from memory_profiler import profile@profile
def broadcast_memory_test():# 创建一个大数组large_array = np.ones((1000, 1000), dtype=np.float64)# 创建一个小数组small_array = np.array([1, 2, 3], dtype=np.float64)# 进行广播运算result = large_array + small_arraybroadcast_memory_test()

注释:

# 导入 NumPy 库,并将其别名为 np
import numpy as np# 导入 memory_profiler 库的 profile 装饰器
from memory_profiler import profile# 使用 @profile 装饰器来监控函数的内存使用情况
@profile
def broadcast_memory_test():# 创建一个大数组# np.ones 是 NumPy 中用于创建全1数组的函数# 传入数组的形状和数据类型作为参数large_array = np.ones((1000, 1000), dtype=np.float64)# 创建一个小数组small_array = np.array([1, 2, 3], dtype=np.float64)# 进行广播运算# 广播机制将 small_array 扩展为与 large_array 相同形状的数组# 然后进行逐元素运算result = large_array + small_array# 运行广播内存测试函数
broadcast_memory_test()
1.3.4 常见广播错误调试技巧

在使用广播机制时,常见的错误是形状不兼容。以下是一些调试技巧:

  1. 检查数组的形状:确保输入数组的形状可以被广播机制处理。
  2. 使用 np.broadcast_arrays:通过 np.broadcast_arrays 函数查看广播后的数组形状。
  3. 使用 np.broadcast_to:通过 np.broadcast_to 函数显式地将数组广播到指定形状。

形状不兼容的典型案例对比(正确 vs 错误)

import numpy as np# 创建一个 3x3 的数组
array3 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])# 创建一个可以广播的一维数组
array1 = np.array([1, 2, 3])
# 创建一个不可以广播的一维数组
array2 = np.array([1, 2])# 正确的广播运算
result1 = array3 + array1
print("正确的广播运算结果:")
print(result1)# 错误的广播运算
try:result2 = array3 + array2
except ValueError as e:print("错误的广播运算结果:")print(e)# 使用 np.broadcast_arrays 检查广播后的形状
broadcasted_arrays = np.broadcast_arrays(array3, array1)
print("广播后的数组形状:")
for b in broadcasted_arrays:print(b.shape)# 使用 np.broadcast_to 显式广播
explicitly_broadcasted = np.broadcast_to(array1, (3, 3))
print("显式广播后的数组:")
print(explicitly_broadcasted)

注释:

# 导入 NumPy 库,并将其别名为 np
import numpy as np# 创建一个 3x3 的数组
array3 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])# 创建一个可以广播的一维数组
array1 = np.array([1, 2, 3])
# 创建一个不可以广播的一维数组
array2 = np.array([1, 2])# 正确的广播运算
# array1 的形状为 (3,),可以广播为 (3, 3)
result1 = array3 + array1
print("正确的广播运算结果:")  # 打印结果
print(result1)# 错误的广播运算
# array2 的形状为 (2,),不能广播为 (3, 3)
try:result2 = array3 + array2
except ValueError as e:print("错误的广播运算结果:")  # 打印错误信息print(e)# 使用 np.broadcast_arrays 检查广播后的形状
# np.broadcast_arrays 是 NumPy 中用于返回广播后的数组的函数
# 传入两个数组作为参数
broadcasted_arrays = np.broadcast_arrays(array3, array1)
print("广播后的数组形状:")  # 打印广播后的数组形状
for b in broadcasted_arrays:print(b.shape)# 使用 np.broadcast_to 显式广播
# np.broadcast_to 是 NumPy 中用于显式将数组广播到指定形状的函数
# 传入数组和目标形状作为参数
explicitly_broadcasted = np.broadcast_to(array1, (3, 3))
print("显式广播后的数组:")  # 打印显式广播后的数组
print(explicitly_broadcasted)
1.3.5 广播在机器学习中的应用实例(如特征归一化)

广播机制在机器学习中非常有用,尤其是在特征归一化等操作中。以下是一个特征归一化的示例:

import numpy as np# 创建一个特征矩阵
X = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=np.float64)# 计算每列的均值
mean = np.mean(X, axis=0)
print("每列的均值:")
print(mean)# 计算每列的标准差
std = np.std(X, axis=0)
print("每列的标准差:")
print(std)# 进行特征归一化
normalized_X = (X - mean) / std
print("归一化后的特征矩阵:")
print(normalized_X)

注释:

# 导入 NumPy 库,并将其别名为 np
import numpy as np# 创建一个特征矩阵
# np.array 是 NumPy 中用于创建数组的函数
# 传入二维列表,每个子列表代表一个样本的特征
X = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=np.float64)# 计算每列的均值
# np.mean 是 NumPy 中用于计算均值的函数
# 传入数组和 axis 参数(0 表示按列计算均值)
mean = np.mean(X, axis=0)
print("每列的均值:")  # 打印每列的均值
print(mean)# 计算每列的标准差
# np.std 是 NumPy 中用于计算标准差的函数
# 传入数组和 axis 参数(0 表示按列计算标准差)
std = np.std(X, axis=0)
print("每列的标准差:")  # 打印每列的标准差
print(std)# 进行特征归一化
# 广播机制将 mean 和 std 扩展为与 X 相同形状的数组
# 然后进行逐元素运算
normalized_X = (X - mean) / std
print("归一化后的特征矩阵:")  # 打印归一化后的特征矩阵
print(normalized_X)

1.3.6 广播与循环操作的性能对比实验

我们将通过一个性能对比实验来验证广播机制与传统循环操作之间的性能差异。实验中,我们将进行两个 1000x1000 数组的逐元素加法运算。

实验代码:

import numpy as np
import time# 创建两个 1000x1000 的数组
array1 = np.random.rand(1000, 1000)
array2 = np.random.rand(1000, 1000)# 使用广播机制进行加法运算
start_time = time.time()
result_broadcast = array1 + array2
broadcast_time = time.time() - start_time# 使用传统循环操作进行加法运算
start_time = time.time()
result_loop = np.zeros((1000, 1000), dtype=np.float64)
for i in range(1000):for j in range(1000):result_loop[i, j] = array1[i, j] + array2[i, j]
loop_time = time.time() - start_time# 打印结果
print("广播机制加法运算时间: {:.6f} 秒".format(broadcast_time))
print("传统循环加法运算时间: {:.6f} 秒".format(loop_time))

注释:

# 导入 NumPy 库,并将其别名为 np
import numpy as np# 导入 time 模块,用于测量时间
import time# 创建两个 1000x1000 的数组
# np.random.rand 是 NumPy 中用于生成随机数组的函数
# 传入数组的形状作为参数
array1 = np.random.rand(1000, 1000)
array2 = np.random.rand(1000, 1000)# 使用广播机制进行加法运算
# 记录开始时间
start_time = time.time()
# 进行加法运算
# 广播机制自动扩展数组的维度并进行逐元素运算
result_broadcast = array1 + array2
# 记录结束时间
broadcast_time = time.time() - start_time# 使用传统循环操作进行加法运算
# 记录开始时间
start_time = time.time()
# 创建一个 1000x1000 的零数组,用于存储结果
result_loop = np.zeros((1000, 1000), dtype=np.float64)
# 逐元素进行加法运算
for i in range(1000):for j in range(1000):result_loop[i, j] = array1[i, j] + array2[i, j]
# 记录结束时间
loop_time = time.time() - start_time# 打印结果
# 打印广播机制加法运算的时间
print("广播机制加法运算时间: {:.6f} 秒".format(broadcast_time))
# 打印传统循环加法运算的时间
print("传统循环加法运算时间: {:.6f} 秒".format(loop_time))

实验结果分析:

运行上述代码后,我们通常会发现广播机制的加法运算时间远远少于传统循环操作的加法运算时间。这是因为在广播机制中,NumPy 通过底层的 C 语言实现高效的逐元素运算,而传统循环操作则需要解释器逐行解释和执行 Python 代码,这通常会导致性能下降。

1.3.7 广播机制的综合应用示例

为了进一步展示广播机制的强大功能,我们来看一个更复杂的综合应用示例。假设我们有一个二维数组表示图像的像素值,我们希望对图像的每个通道进行不同的归一化处理。

代码示例:

import numpy as np# 创建一个 4x4x3 的图像数组
image = np.random.rand(4, 4, 3)# 每个通道的均值和标准差
mean = np.array([0.5, 0.4, 0.3])
std = np.array([0.1, 0.2, 0.3])# 进行特征归一化
# 使用广播机制将 mean 和 std 扩展为与 image 相同形状的数组
normalized_image = (image - mean) / std# 打印结果
print("归一化后的图像数组:")
print(normalized_image)

注释:

# 导入 NumPy 库,并将其别名为 np
import numpy as np# 创建一个 4x4x3 的图像数组
# 4x4 表示图像的宽和高,3 表示每个像素有3个通道(例如RGB)
image = np.random.rand(4, 4, 3)# 每个通道的均值
# mean 是一个形状为 (3,) 的数组,表示每个通道的均值
mean = np.array([0.5, 0.4, 0.3])# 每个通道的标准差
# std 是一个形状为 (3,) 的数组,表示每个通道的标准差
std = np.array([0.1, 0.2, 0.3])# 进行特征归一化
# 使用广播机制将 mean 和 std 扩展为与 image 相同形状的数组
# 然后进行逐元素运算
normalized_image = (image - mean) / std# 打印结果
# 打印归一化后的图像数组
print("归一化后的图像数组:")
print(normalized_image)

结论

NumPy 的广播机制是一个非常强大的工具,可以帮助我们轻松地进行不同形状数组的运算,而无需显式地扩展数组的维度。通过本文的介绍和示例,我们不仅了解了广播机制的基本规则和原理,还学会了如何调试常见的广播错误和优化内存使用。在实际应用中,广播机制可以显著提高代码的效率和可读性,尤其是在机器学习和图像处理等领域。

希望本文对大家有所帮助,如果有任何问题或建议,欢迎在评论区留言!

参考文献

参考资料链接
NumPy 官方文档https://numpy.org/doc/stable/
Numpy 广播机制详解https://www.jianshu.com/p/7d5b1e75d9d5
NumPy 源码分析https://github.com/numpy/numpy/blob/main/numpy/core/src/multiarray/mapping.c
Python 科学计算库NumPy入门https://www.cnblogs.com/pinard/p/6244261.html
NumPy 广播机制深入理解https://www.datacamp.com/community/tutorials/numpy-tutorial-python#broadcasting
NumPy 与内存优化https://realpython.com/numpy-array-programming/
NumPy 广播规则https://numpy.org/doc/stable/user/basics.broadcasting.html
NumPy 广播机制的原理https://www.geeksforgeeks.org/numpy-broadcasting-how-and-why-use-it/
广播机制在机器学习中的应用https://machinelearningmastery.com/broadcasting-with-numpy-arrays/
Python 性能优化技巧https://www.toptal.com/python/an-in-depth-guide-to-profiling-in-python
NumPy 与 Python 内存管理https://pythonspeed.com/articles/numpy-memory-usage/

希望这篇文章能帮助你更好地理解和应用 NumPy 的广播机制。这篇文章包含了详细的原理介绍、代码示例、源码注释以及案例等。希望这对您有帮助。如果有任何问题请随私信或评论告诉我。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/8049.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Semantic Kernel - Kernel理解

目录 一、关于Kernel 二、案例实战 三、运行截图 一、关于Kernel 微软的 Semantic Kernel 项目中,Semantic Kernel 是一个工具框架,旨在使得开发人员能够更容易地将大语言模型(如GPT)集成到不同的应用中。它通过提供一组接口、任务模板和集成模块,使开发者能够轻松地设计…

【MySQL】--- 复合查询 内外连接

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏: MySQL 🏠 基本查询回顾 假设有以下表结构: 查询工资高于500或岗位为MANAGER的雇员,同时还要满足他们的姓名首字母为…

Qt Designer and Python: Build Your GUI

1.install pyside6 2.pyside6-designer.exe 发送到桌面快捷方式 在Python安装的所在 Scripts 文件夹下找到此文件。如C:\Program Files\Python312\Scripts 3. 打开pyside6-designer 设计UI 4.保存为simple.ui 文件,再转成py文件 用代码执行 pyside6-uic.exe simpl…

openlayer getLayerById 根据id获取layer图层

背景: 在项目中使用getLayerById获取图层,这个getLayerById()方法不是openlayer官方文档自带的,而是自己封装的一个方法,这个封装的方法的思路是:遍历所有的layer,根据唯一标识【可能是id,也可能…

Qt 控件与布局管理

1. Qt 控件的父子继承关系 在 Qt 中,继承自 QWidget 的类,通常会在构造函数中接收一个 parent 参数。 这个参数用于指定当前空间的父控件,从而建立控件间的父子关系。 当一个控件被设置为另一控件的子控件时,它会自动成为该父控…

SOME/IP--协议英文原文讲解1

前言 SOME/IP协议越来越多的用于汽车电子行业中,关于协议详细完全的中文资料却没有,所以我将结合工作经验并对照英文原版协议做一系列的文章。基本分三大块: 1. SOME/IP协议讲解 2. SOME/IP-SD协议讲解 3. python/C举例调试讲解 一、SOM…

Ansible自动化运维实战--script、unarchive和shell模块(6/8)

文章目录 一、script模块1.1、功能1.2、常用参数1.3、举例 二、unarchive模块2.1、功能2.2、常用参数2.3、举例 三、shell模块3.1、功能3.2、常用参数3.3、举例 一、script模块 1.1、功能 Ansible 的 script 模块允许你在远程主机上运行本地的脚本文件,其提供了一…

【模型】RNN模型详解

1. 模型架构 RNN(Recurrent Neural Network)是一种具有循环结构的神经网络,它能够处理序列数据。与传统的前馈神经网络不同,RNN通过将当前时刻的输出与前一时刻的状态(或隐藏层)作为输入传递到下一个时刻&…

《FreqMamba: 从频率角度审视图像去雨问题》学习笔记

paper:FreqMamba: Viewing Mamba from a Frequency Perspective for Image Deraining GitHub:GitHub - aSleepyTree/FreqMamba 目录 摘要 1、介绍 2、相关工作 2.1 图像去雨 2.2 频率分析 2.3 状态空间模型 3、方法 3.1 动机 3.2 预备知识 3…

iic、spi以及uart

何为总线? 连接多个部件的信息传输线,是部件共享的传输介质 总线的作用? 实现数据传输,即模块之间的通信 总线如何分类? 根据总线连接的外设属于内部外设还是外部外设将总线可以分为片内总线和片外总线 可分为数…

Android WebView 中网页被劫持的原因及解决方案

文章目录 一、原因分析二、解决方案一览三、解决方案代码案例3.1 使用 HTTPS3.2 验证 URL3.3 禁用 JavaScript3.4 使用安全的 WebView 设置3.5 监控网络请求3.6 使用安全的 DNS 四、案例深入分析4.1 问题4.2 分析 五、结论 在 Android 应用开发中,WebView 是一个常用…

Linux——网络(udp)

文章目录 目录 文章目录 前言 一、upd函数及接口介绍 1. 创建套接字 - socket 函数 2. 绑定地址和端口 - bind 函数 3. 发送数据 - sendto 函数 4. 接收数据 - recvfrom 函数 5. 关闭套接字 - close 函数 二、代码示例 1.服务端 2.客户端 总结 前言 Linux——网络基础&#xf…

C语言学习强化

前言 数据的逻辑结构包括: 常见数据结构: 线性结构:数组、链表、队列、栈 树形结构:树、堆 图形结构:图 一、链表 链表是物理位置不连续,逻辑位置连续 链表的特点: 1.链表没有固定的长度…

【ArcGIS微课1000例】0141:提取多波段影像中的单个波段

文章目录 一、波段提取函数二、加载单波段导出问题描述:如下图所示,img格式的时序NDVI数据有24个波段。现在需要提取某一个波段,该怎样操作? 一、波段提取函数 首先加载多波段数据。点击【窗口】→【影像分析】。 选择需要处理的多波段影像,点击下方的【添加函数】。 在多…

css3 svg制作404页面动画效果HTML源码

源码介绍 css3 svg制作404页面动画效果HTML源码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果 效果预览 源码如下 <!doctype html> <html> <head> <meta charse…

R语言学习笔记之高效数据操作

一、概要 数据操作是R语言的一大优势&#xff0c;用户可以利用基本包或者拓展包在R语言中进行复杂的数据操作&#xff0c;包括排序、更新、分组汇总等。R数据操作包&#xff1a;data.table和tidyfst两个扩展包。 data.table是当前R中处理数据最快的工具&#xff0c;可以实现快…

利用Qt5.15.2编写Android程序时遇到的问题及解决方法

文章目录 背景1.文件读写 背景 目前我用的是Qt5.15.2来编写Qt程序&#xff0c;环境的配置看我这篇文章【Qt5.15.2配置Android开发环境】 项目中的一些配置的截图&#xff1a; 1.文件读写 假如直接用 QFileDialog::getExistingDirectory来获取路径的话&#xff0c;会得到类…

【学术会议-第五届机械设计与仿真国际学术会议(MDS 2025) 】前端开发:技术与艺术的完美融合

重要信息 大会官网&#xff1a;www.icmds.net 大会时间&#xff1a;2025年02月28日-03月02日 大会地点&#xff1a;中国-大连 会议简介 2025年第五届机械设计与仿真国际学术会议&#xff08;MDS 2025) 将于2025年02月28-3月02日在中国大连召开。MDS 2025将围绕“机械设计”…

leetcode刷题记录(一百)——121. 买卖股票的最佳时机

&#xff08;一&#xff09;问题描述 121. 买卖股票的最佳时机 - 力扣&#xff08;LeetCode&#xff09;121. 买卖股票的最佳时机 - 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。你只能选择 某一天 买入这只股票&#xff0c;并…

亲测有效!解决PyCharm下PyEMD安装报错 ModuleNotFoundError: No module named ‘PyEMD‘

解决PyCharm下PyEMD安装报错 PyEMD安装报错解决方案 PyEMD安装报错 PyCharm下通过右键自动安装PyEMD后运行报错ModuleNotFoundError: No module named ‘PyEMD’ 解决方案 通过PyCharm IDE python package搜索EMD-signal&#xff0c;选择版本后点击“install”执行安装