如何将NumPy数组元素传入sim_projectile函数批量获取抛射体位置输出?
嘿,这个需求其实挺典型的,我给你整理了几种实用的解决办法,你可以根据自己的场景选:
解法1:基础循环法(直观易懂)
这是最容易理解的方式,遍历angle_array里的每个角度,逐个调用函数并收集结果:
import numpy as np # 先模拟你的函数实现(方便测试) def sim_projectile(time_array, m, c, v0, theta0d): theta0 = np.deg2rad(theta0d) v0x = v0 * np.cos(theta0) v0y = v0 * np.sin(theta0) # 这里省略了空气阻力的计算,你可以替换成自己的逻辑 position_x = v0x * time_array position_y = v0y * time_array - 0.5 * 9.8 * time_array**2 return position_x, position_y # 假设这些变量已经定义好 time_array = np.linspace(0, 10, 100) m = 1.0 c = 0.1 v0 = 20.0 angle_array = np.arange(20, 61, 1) # 初始化列表来存储所有结果 all_pos_x = [] all_pos_y = [] # 遍历每个角度 for theta in angle_array: x, y = sim_projectile(time_array, m, c, v0, theta) all_pos_x.append(x) all_pos_y.append(y) # 转换成numpy数组方便后续分析(可选) all_pos_x = np.array(all_pos_x) all_pos_y = np.array(all_pos_y)
最终all_pos_x和all_pos_y的形状是(41, 100)——对应41个角度,每个角度下100个时间点的位置数据。
解法2:列表推导式(简洁写法)
如果觉得循环太啰嗦,可以用列表推导式压缩代码,效果和循环完全一致:
# 用列表推导式一次性生成所有(x,y)对,再拆分 all_pos_x, all_pos_y = zip(*[sim_projectile(time_array, m, c, v0, theta) for theta in angle_array]) # 转成numpy数组 all_pos_x = np.array(all_pos_x) all_pos_y = np.array(all_pos_y)
这里的zip(*...)会把每个函数返回的(x,y)元组拆分成两个独立的元组,刚好对应所有x和y的结果。
解法3:用
np.vectorize包装函数(伪向量化风格) 如果你想让函数看起来像原生支持数组输入,可以用np.vectorize包装一下它。注意这本质还是循环,但写法更贴近numpy的风格:
# 用signature指定输入输出的形状,确保vectorize能正确处理 vec_projectile = np.vectorize( sim_projectile, signature='(n),(),(),(),()->(n),(n)' ) # 直接传入整个angle_array,无需循环 all_pos_x, all_pos_y = vec_projectile(time_array, m, c, v0, angle_array)
signature参数的意思是:输入是一个长度为n的数组(time_array)、三个标量(m,c,v0)、一个标量(theta0d);输出是两个长度为n的数组。这样包装后,函数就能直接接受angle_array作为输入了。
解法4:修改函数支持原生向量化(最高效推荐)
如果允许修改原函数,那直接让它支持数组输入是最高效的方式——利用numpy的广播机制,避免循环,速度会快很多:
def sim_projectile_vectorized(time_array, m, c, v0, theta0d): theta0 = np.deg2rad(theta0d) # 给theta0增加一个维度,让它能和time_array广播 v0x = v0 * np.cos(theta0)[:, np.newaxis] v0y = v0 * np.sin(theta0)[:, np.newaxis] # 利用广播直接计算所有角度的位置 position_x = v0x * time_array position_y = v0y * time_array - 0.5 * 9.8 * time_array**2 return position_x, position_y # 直接传入angle_array,一步到位 all_pos_x, all_pos_y = sim_projectile_vectorized(time_array, m, c, v0, angle_array)
这里的[:, np.newaxis]把theta0从形状(41,)变成(41,1),这样和形状(100,)的time_array运算时,numpy会自动把它们广播成(41,100)的数组,一次性算出所有角度的结果,效率拉满。
内容的提问来源于stack exchange,提问作者Human Error
相关产品推荐
相关产品推荐

