【问题标题】:Division by 0 in python broadcasting?在python广播中除以0?
【发布时间】:2019-03-15 17:14:58
【问题描述】:

我正在使用 Python2.7 创建一个简单的向量场,然后将其绘制出来......

但是 Jupyter 抱怨除以 0(“RuntimeWarning:除以零时遇到除数”),我找不到它。

import numpy as np

def field_gen(x0, y0, x, y, q_cons = 1):
    dx = x0-x
    dy = y0-y
    dist = np.sqrt(np.square(dx)+np.square(dy))
    kmod = np.where( dist>0.00001, q_cons / dist, 0  ) 
    kdir = np.where( kmod != 0, (np.arctan2(-dy,-dx) * 180 / np.pi), 0)
    res_X = np.where( kmod !=0, kmod * (np.cos(kdir)) , 0 )
    res_Y = np.where( kmod !=0, kmod * (np.sin(kdir)) , 0 )
    return (res_X, res_Y)

n = 10
X, Y = np.mgrid[0:n, 0:n]

x0=2
y0=2

(u,v)= field_gen(x0, y0, X, Y)
#print(u) #debug
#print
#print(v)
plt.figure()
plt.quiver(X, Y, u, v, units='width')

有什么提示吗?

【问题讨论】:

  • 虽然np.where 可以用来表示“这是真的,使用这个;否则做那个”,它仍然会首先评估整个q_cons / distdist 将在 [2,2] 处有一个零条目。因此错误。
  • 感谢@freethebees,我还是 Python 新手。有没有不首先评估语句的替代方案?
  • 别担心!这是一个经典的 Python 陷阱。请看下面我的回答。 np.dividedist > 0.001 作为输入并使用它来遍历您的数组。在 Python 中手动迭代会很慢,但 NumPy 有一些很棒的编译内容,可以为你快速完成这种事情。
  • 嗯,它有效,再次感谢!我正在尝试一种丑陋的类似 c 的方法...在两者之间使用“dist = np.where(dist > 0, dist, np.inf)”。但是,使用您的解决方案,在 [2,2] 的情况下,它返回一个 0,我想知道这是否是 np.divide 的默认行为...... docs 说“False 值表示保留该值仅在输出中”,但由于未提供输出数组(“如果未提供或无,则返回新分配的数组”),因此分配为零?
  • out 允许您定义一个数组来放入结果。据我了解,如果该数组是一个充满了的数组,那么where 中的False 单元格将成为一个。如果您不提供out,那么它会创建一个空白数组并使用q_cons 中的值。不过,您必须玩一会儿才能确定。很高兴我能帮上忙。

标签: python numpy vectorization array-broadcasting divide-by-zero


【解决方案1】:

不要误以为np.where 在这里完成了所有工作。在调用np.where 之前,Python 仍将首先评估所有输入参数。

因此,在您的命令 kmod = np.where( dist>0.00001, q_cons / dist, 0 ) 中,Python 将在运行 np.where 之前评估 dist>0.00001(正常)和 q_cons / dist(糟糕!)。

改用np.divide。我想你想要这样的东西:

np.divide(q_cons, dist, where=dist>0.00001 )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-11
    • 2013-09-11
    • 2017-04-19
    • 1970-01-01
    • 1970-01-01
    • 2014-05-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多