【问题标题】:Numpy cumsum considering NaNs考虑到 NaN 的 Numpy cumsum
【发布时间】:2012-10-14 14:30:33
【问题描述】:

我正在寻找一种简洁的方式:

 a = numpy.array([1,4,1,numpy.nan,2,numpy.nan])

到:

  b = numpy.array([1,5,6,numpy.nan,8,numpy.nan])

目前我能做的最好的事情是:

b = numpy.insert(numpy.cumsum(a[numpy.isfinite(a)]), (numpy.argwhere(numpy.isnan(a)) - numpy.arange(len(numpy.argwhere(numpy.isnan(a))))), numpy.nan)

有没有更短的方法来完成同样的事情?沿着二维数组的轴做一个 cumsum 怎么样?

【问题讨论】:

  • numpy 在 1.12.0 版本中添加了 nancumsum 函数。它并不能直接做你想做的事,因为它会给你结果[1, 5, 6, 6, 8, 8]

标签: python arrays numpy nan cumsum


【解决方案1】:

Pandas 是在numpy 之上构建的库。它是 Series 类有一个 cumsum 方法,它保留了 nan 的方法,并且比 DSM 提出的解决方案快得多:

In [15]: a = arange(10000.0)

In [16]: a[1] = np.nan

In [17]: %timeit a*0 + np.nan_to_num(a).cumsum()
1000 loops, best of 3: 465 us per loop

In [18] s = pd.Series(a)

In [19]: s.cumsum()
Out[19]: 
0       0
1     NaN
2       2
3       5
...
9996    49965005
9997    49975002
9998    49985000
9999    49994999
Length: 10000

In [20]: %timeit s.cumsum()
10000 loops, best of 3: 175 us per loop

【讨论】:

    【解决方案2】:

    怎么样(对于不太大的数组):

    In [34]: import numpy as np
    
    In [35]: a = np.array([1,4,1,np.nan,2,np.nan])
    
    In [36]: a*0 + np.nan_to_num(a).cumsum()
    Out[36]: array([  1.,   5.,   6.,  nan,   8.,  nan])
    

    【讨论】:

      【解决方案3】:

      Masked arrays 仅适用于这种情况。

      >>> import numpy as np
      >>> from numpy import ma
      >>> a = np.array([1,4,1,np.nan,2,np.nan])
      >>> b = ma.masked_array(a,mask = (np.isnan(a) | np.isinf(a)))
      >>> b
      masked_array(data = [1.0 4.0 1.0 -- 2.0 --],
               mask = [False False False  True False  True],
         fill_value = 1e+20)
      >>> c = b.cumsum()
      >>> c
      masked_array(data = [1.0 5.0 6.0 -- 8.0 --],
               mask = [False False False  True False  True],
         fill_value = 1e+20)
      >>> c.filled(np.nan)
      array([  1.,   5.,   6.,  nan,   8.,  nan])
      

      【讨论】:

        猜你喜欢
        • 2012-09-07
        • 2021-09-10
        • 1970-01-01
        • 1970-01-01
        • 2013-08-14
        • 2018-07-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多