【问题标题】:How to add/sum values from separate lists如何从单独的列表中添加/求和值
【发布时间】:2017-07-26 18:49:13
【问题描述】:

我有一个要加在一起的个位数列表。

我是从这个开始的:

d3 = [9,9,9,8]
d4 = [3,6,np.nan,10]

for i,j in enumerate(d3):
    add = [(d3[i]-d4[i])**2]

当我执行上面的代码时,我得到以下列表:

[36]
[9]
[nan]
[4]

但是,我想要这些数字的总和,而忽略 NaN(所需的输出是 36+9+4):

【问题讨论】:

标签: python list numpy enumerate


【解决方案1】:

对于 numpy 中的快速代码,您希望尽可能避免循环。转换为 numpy 数组(坦率地说,最好用它们开始,否则每次转换都会输!),应用向量运算,然后使用np.nansum

In [9]: np.array(d3) - np.array(d4)
Out[9]: array([  6.,   3.,  nan,  -2.])

In [10]: (np.array(d3) - np.array(d4))**2
Out[10]: array([ 36.,   9.,  nan,   4.])

In [11]: np.nansum((np.array(d3) - np.array(d4))**2)
Out[11]: 49.0

为了比较,如果我们开始使用 numpy 数组,阅读起来会更好:

In [14]: d3 = np.array(d3); d4 = np.array(d4)

In [15]: np.nansum((d3-d4)**2)
Out[15]: 49.0

【讨论】:

    【解决方案2】:
    >>> import numpy as np
    
    >>> d3 = [9,9,9,8]
    >>> d4 = [3,6,np.nan,10]
    >>> total = np.nansum([(a-b)**2 for a,b in zip(d3, d4)])
    49.0
    

    编辑

    这里有一些测试显示这需要多长时间,使用列表、np.array 以及动态将列表转换为 np.array:

    >>> import numpy as np
    
    >>> short_l1 = [9,9,9,8]
    >>> short_l2 = [3,6,np.nan,10]
    >>> long_l1 = short_l1 * 1000
    >>> long_l2 = short_l2 * 1000
    
    >>> short_a1 = np.array(short_l1)
    >>> short_a2 = np.array(short_l2)
    >>> long_a1 = np.array(long_l1)
    >>> long_a2 = np.array(long_l2)
    
    >>> %timeit np.nansum([(a-b)**2 for a,b in zip(short_l1 , short_l2)])
    9.1 µs ± 29.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
    
    >>> %timeit np.nansum((np.array(short_l1)-np.array(short_l2))**2)
    12 µs ± 112 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
    
    >>> %timeit np.nansum((short_a1-short_a2)**2)
    9.07 µs ± 24.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
    
    >>> %timeit np.nansum([(a-b)**2 for a,b in zip(long_l1 , long_l2)])
    1.32 ms ± 15.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
    
    >>> %timeit np.nansum((np.array(long_l1)-np.array(long_l2))**2)
    498 µs ± 3.07 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
    
    >>> %timeit np.nansum((long_a1-long_a2)**2)
    48.7 µs ± 581 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
    

    如您所见,您绝对应该按照@DSM 的回答去做,当您的数据量增加时,它方式会更快

    【讨论】:

    • 没有。这不是最好的方法。
    • @cᴏʟᴅsᴘᴇᴇᴅ 没有必要将其更改为 numpy 数组,因为已经有其他答案表明了这一点。
    • @cᴏʟᴅsᴘᴇᴇᴅ 添加了一些时机,以便 OP 了解为什么这不是最佳解决方案
    【解决方案3】:

    如果您只想要列表中值的总和而忽略 NaN 值,那么 numpy 中有一个名为 np.nansum() 的内置函数将忽略所有 NaN 值:

    d4 = [3,6,np.nan,10]
    print(np.nansum(d4))
    Out[110]: 19.0
    

    【讨论】:

      【解决方案4】:
      sum([ np.nansum([x,y]) for x,y in zip(d3, d4) ])
      

      或者,适合您的代码而不是请求:

      np.nansum([ (x-y)**2 for x,y in zip(d3, d4) ])
      

      【讨论】:

        【解决方案5】:

        忽略 nan 怎么样:

        for i,j in enumerate(d3):
            if d3[i] != np.nan and d4[i] != np.nan:
                add = [(d3[i]-d4[i])**2]
        

        【讨论】:

          【解决方案6】:

          您不能使用 null/nan 对象/基元来操作数字。 另外,您减去不添加的 pow 值(??????)。 要添加,您必须:

          d3 = [9,9,9,8]
          d4 = [3,6,2,10]
          add=None
          for i,j in enumerate(d3):
              add = d3[i]+d4[i]
              print(add)
          

          【讨论】:

          • 这对 OP 一点用处都没有。
          猜你喜欢
          • 2020-05-21
          • 2018-07-28
          • 2013-05-14
          • 1970-01-01
          • 1970-01-01
          • 2023-01-25
          • 1970-01-01
          • 2020-09-30
          • 1970-01-01
          相关资源
          最近更新 更多