【问题标题】:Make division by zero equal to zero in a list使除以零等于列表中的零
【发布时间】:2018-06-10 13:39:36
【问题描述】:

我有一个列表L,我想计算每个元素const/L_j,并获得一个新列表M,其中包含元素M_j = const/L_j。但是,有L_j 元素为零。在这种情况下,最好将这种除法分配为零。我已将其作为下面的脚本,但速度很慢。

temp = np.zeros((self.n_features, 1))
for t in range(self.n_features):
    if y[t]!=0:
        temp[t] = x/y[t] 

我的问题与此类似,但我想将其应用到列表中。这些是计算列表M 的更快方法吗?

谢谢。

【问题讨论】:

  • 没有一种计算速度更快的方法来计算这个列表。您最多只能做一次访问来计算每个元素,而且不能少做。
  • @NiVeR:NumPy 的目的是通过矢量化加速此类计算;在这种情况下这样做比天真的循环解决方案快几个数量级。

标签: python numpy divide-by-zero


【解决方案1】:

时间复杂度为O(N) 的另一种方式,遍历元素:

M = [0 if l == 0 else constant/l for l in L]

【讨论】:

  • 复杂性在这里几乎无关紧要;矢量化解决方案也将是线性时间,但常数要小几个数量级。
  • @fuglede 你是完全正确的,关键是它可以通过对数据的 1 次迭代来完成(无系数)。
【解决方案2】:

假设您的数组名为 L,您可以执行类似的操作

M = x/L
M[np.isinf(M)] = 0

将坏元素归零所需的额外时间可以忽略不计,即使无穷大的数量很大:

In [20]: L = np.random.randint(0, 2, 100000)

In [21]: %timeit [0 if l == 0 else 10/l for l in L]
34.9 ms ± 2.03 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [23]: %timeit M = 10/L
263 µs ± 11.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [24]: %timeit M[np.isinf(M)] = 0
983 ns ± 40.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

【讨论】:

    【解决方案3】:
    def transform_to_M(const, x):
        if x==0:
           return 0
        return const/x
    
    np.fromiter((transform_to_M(const, i) for i in y), float, count=len(y))
    

    【讨论】:

      【解决方案4】:

      您可以使用math.inf 来完成。

      from math import inf
      
      lst = [2, 1, 0, -1, -2]
      const = 1
      
      res = [const / (l or inf) for l in lst]
      
      print(res) # [0.5, 1.0, 0.0, -1.0, -0.5]
      

      【讨论】:

        【解决方案5】:

        最快、最简单和最 Pythonic 的方法是数组掩码:

        M = x / L
        M[L == 0] = 0
        

        这是一个比 fuglede 的代码更快的函数评估。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-03-09
          • 1970-01-01
          • 2016-04-06
          • 2017-07-20
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多