np.divide(x, y)和x/y在Python3中有什么区别?

2 投票
1 回答
82 浏览
提问于 2025-04-14 16:08

我最近在代码里发现了一个错误,通过把 np.divide(x, y) 替换成 x / y 来解决了这个问题。

我原本以为 np.divide(x, y)x / y 是一样的(在numpy的文档里也是这么说的)。

这算不算numpy的一个bug,还是说这是正常的行为呢?

就像我说的,我现在的问题已经解决了,所以我并不太担心找到修复方法,我更想搞清楚到底发生了什么。

import numpy as np


x1 = np.array([[281], [15831], [30280], [975], [313], [739], [252], [10364], [21480], [1447], [315], [772], [95], [2710], [7408], [215], [111], [158], [0], [88], [21], [661], [0], [0], [0], [5], [4], [0], [12], [0], [0], [50], [28], [0], [0], [272]])
x2 = np.array([[499], [6315], [33800], [580], [208], [464], [384], [3127], [19596], [2319], [218], [1740], [217], [411], [4250], [223], [406], [267], [2], [0], [16], [0], [0], [0], [0], [8], [3], [0], [18], [0], [1], [0], [41], [0], [0], [0]])
x3 = np.array([[507], [6180], [34005], [555], [200], [451], [390], [3024], [19492], [2425], [211], [1848], [223], [396], [4097], [224], [406], [282], [2], [0], [16], [0], [0], [0], [0], [8], [3], [0], [19], [0], [2], [0], [45], [0], [0], [0]])
x4 = np.array([[507], [6178], [34017], [554], [200], [451], [391], [3022], [19486], [2439], [210], [1865], [223], [396], [4089], [224], [406], [284], [2], [0], [16], [0], [0], [0], [0], [8], [3], [0], [19], [0], [2], [0], [46], [0], [0], [0]])

not_zero = (x1 + x2) != 0
x = np.divide(2*(x1 - x2)**2, x1 + x2, where=not_zero)
r = (2*(x1[not_zero] - x2[not_zero])**2) / (x1[not_zero] + x2[not_zero])
print("n1 =",x.max(),"\tt1 =", r.max())

not_zero = (x2 + x3) != 0
x = np.divide(2*(x2 - x3)**2, x2 + x3, where=not_zero)
r = (2*(x2[not_zero] - x3[not_zero])**2) / (x2[not_zero] + x3[not_zero])
print("n2 =",x.max(),"\tt2 =", r.max())

not_zero = (x3 + x4) != 0
x = np.divide(2*(x3 - x4)**2, x3 + x4, where=not_zero)
r = (2*(x3[not_zero] - x4[not_zero])**2) / (x3[not_zero] + x4[not_zero])
print("n3 =",x.max(),"\tt3 =", r.max())

输出:

n1 = 8177.933351395286  t1 = 8177.933351395286
n2 = 873842.0           t2 = 6.501672240802676
n3 = 1322.0             t3 = 0.15566927013196877

Python版本:3.7.6 Numpy版本:1.17.0

1 个回答

6

参数 where = mask 如果没有 out 参数的话,其实是有点危险的。因为没有指定输出的目标,这个函数会创建一个形状合适的 np.empty 数组,然后用一些输出数据去替换这个空数组中的部分内容。

但是 np.empty 其实并不是“空”的。它只是一个随机的内存位置,里面的内容没有被初始化(所以它可能还保留着之前在这个内存块中存在的垃圾数据)。所以当 mask = False 的时候,你的输出就会是那些剩下的随机垃圾。如果这个内存块恰好有一些可以转化为比你其他数据还大的数字的垃圾数据,它就可能成为你的 max 值。

你可以用 not_zero 再次作为掩码来去掉这些垃圾数据:

x = np.divide(2*(x1 - x2)**2, x1 + x2, where=not_zero)[not_zero]

或者你也可以自己初始化输出数组:

x = np.zeros_like(x1)
np.divide(2*(x1 - x2)**2, x1 + x2, where = not_zero, out = x)

撰写回答