优化DataFrame中矩阵乘法以提升飞行器迎角与侧滑角计算效率
优化飞行器相对速度计算的思路(基于Pandas/NumPy)
你的代码核心性能瓶颈在于**iterrows()逐行迭代+手动三重循环**,这两种操作在处理大数据量时效率极低。以下是具体优化方案,全部基于NumPy的向量化运算(底层为C实现,性能比纯Python循环高几个数量级):
方案1:直接展开矩阵运算(最优性能)
直接把矩阵乘法的计算式展开,避免中间数组的创建,用元素级向量化运算完成计算:
# 提前计算所有三角函数值,避免重复计算 cos_pitch = np.cos(df['Pitch']) sin_pitch = np.sin(df['Pitch']) cos_yaw = np.cos(df['Yaw']) sin_yaw = np.sin(df['Yaw']) cos_roll = np.cos(df['Roll']) sin_roll = np.sin(df['Roll']) # 提取全局速度向量为NumPy数组 V_global = df[['Vx', 'Vy', 'Vz']].values # 直接展开旋转矩阵与速度向量的点乘计算 df['Vxx'] = cos_pitch * cos_yaw * V_global[:,0] + cos_pitch * sin_yaw * V_global[:,1] - sin_pitch * V_global[:,2] df['Vyy'] = (sin_pitch * sin_roll * cos_yaw - cos_roll * sin_yaw) * V_global[:,0] + \ (sin_pitch * sin_roll * sin_yaw + cos_roll * cos_yaw) * V_global[:,1] + \ sin_roll * cos_pitch * V_global[:,2] df['Vzz'] = (cos_yaw * cos_roll * sin_pitch + sin_roll * sin_yaw) * V_global[:,0] + \ (sin_yaw * cos_roll * sin_pitch - sin_roll * cos_yaw) * V_global[:,1] + \ cos_roll * cos_pitch * V_global[:,2]
方案2:批量矩阵乘法(更直观)
如果想保留矩阵运算的逻辑清晰性,可以构造三维旋转矩阵数组,批量完成所有行的矩阵乘法:
# 提前计算三角函数值 cos_pitch = np.cos(df['Pitch']) sin_pitch = np.sin(df['Pitch']) cos_yaw = np.cos(df['Yaw']) sin_yaw = np.sin(df['Yaw']) cos_roll = np.cos(df['Roll']) sin_roll = np.sin(df['Roll']) # 构造三维旋转矩阵数组:shape为(数据行数, 3, 3) rot_matrices = np.stack([ np.stack([cos_pitch*cos_yaw, cos_pitch*sin_yaw, -sin_pitch], axis=1), np.stack([ sin_pitch*sin_roll*cos_yaw - cos_roll*sin_yaw, sin_pitch*sin_roll*sin_yaw + cos_roll*cos_yaw, sin_roll*cos_pitch ], axis=1), np.stack([ cos_yaw*cos_roll*sin_pitch + sin_roll*sin_yaw, sin_yaw*cos_roll*sin_pitch - sin_roll*cos_yaw, cos_roll*cos_pitch ], axis=1) ], axis=1) # 全局速度向量reshape为(数据行数, 3, 1) V_global = df[['Vx', 'Vy', 'Vz']].values.reshape(-1, 3, 1) # 批量矩阵乘法计算机体坐标系速度 V_body = np.matmul(rot_matrices, V_global) # 赋值回DataFrame df['Vxx'] = V_body[:, 0, 0] df['Vyy'] = V_body[:, 1, 0] df['Vzz'] = V_body[:, 2, 0]
额外优化建议
- 避免不必要的DataFrame列:原代码中把
a11到a33都存在DataFrame中,如果后续不需要这些中间值,直接用变量计算即可,减少内存占用和DataFrame读写开销。 - 提前缓存三角函数值:原代码多次重复计算
np.cos(df['Pitch'])等,提前缓存这些值能节省重复计算的时间。 - 用
df.assign()链式操作:如果喜欢简洁代码,可以用df.assign()一次性创建所有新列,避免多次修改DataFrame。
内容的提问来源于stack exchange,提问作者Decaff_42
相关产品推荐
相关产品推荐

