Python接收numpy ndarray的含迭代逻辑函数报错如何解决
问题原因
你传入zvdw的Xpr、YTr是meshgrid生成的二维numpy数组,不是单个浮点数:
- 第一个
zshell函数所有运算都是numpy原生支持的向量化运算,全程操作数组不需要逐元素判断条件,所以可以正常运行。 - 而
zvdw函数中,当输入是数组时,计算得到的erro也是和输入同形状的二维数组,Python的while语句无法直接判断「整个数组和阈值比较」的布尔值:它不知道你要求是数组所有元素都满足误差条件,还是任意一个元素满足条件,因此抛出了歧义报错,这个报错确实直接来自while的条件判断逻辑。
解决方案
提供三种可行的解决方式,按需选择:
方案1:改写为向量化迭代(性能最优,推荐)
把zvdw的迭代逻辑改为支持整个数组同步迭代,直到所有元素的误差都达标,修改后的代码如下:
import numpy as np def zvdw(pr_, Tr_): A = 0.421875*pr_/Tr_**2 B = 0.125*pr_/Tr_ # 初始化z为和输入同形状的数组,所有元素初始值为0.95 z = np.full_like(pr_, 0.95) erro = np.ones_like(pr_) # 只要还有任意元素的误差不达标就继续迭代 while erro.max() >= 1.0e-06: c2 = -(B + 1.0) c1 = A c0 = -A*B f = z**3 + c2*z**2 + c1*z + c0 df = 3.0*z**2 + 2.0*c2*z + c1 zf = z - f/df erro = np.abs((zf - z)/z) z = zf return z
这个方案全程用numpy向量化运算,性能远高于循环方案,适合网格点数量大的场景。
方案2:用np.vectorize包装函数(改码最少)
如果不想修改原zvdw的逻辑,可以直接用numpy的vectorize把原函数包装为支持数组输入的版本,调用时改为:
Z = np.vectorize(zvdw)(Xpr, YTr)
注意这个方案本质是自动遍历数组的每个元素调用原函数,性能低于向量化方案,适合小数据量的快速验证。
方案3:逐网格点循环计算(最直观,性能最差)
手动遍历两个维度的每个网格点逐个计算Z值,代码示例:
Z = np.zeros_like(Xpr) for i in range(Xpr.shape[0]): for j in range(Xpr.shape[1]): Z[i,j] = zvdw(Xpr[i,j], YTr[i,j])
这个方案性能最低,仅适合网格点极少的场景使用。
内容的提问来源于stack exchange,提问作者Fausto Arinos Barbuto
相关产品推荐
相关产品推荐

