2012-10-24 15 views
9

Tôi đang tìm kiếm một cách gọn gàng để đi từ:NumPy cumsum xem xét Nans

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

tới:

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

Điều tốt nhất tôi hiện có thể làm là:

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

Is có cách nào ngắn hơn để thực hiện tương tự không? Điều gì về làm một cumsum dọc theo một trục của một mảng 2D?

+0

NumPy có một' chức năng nancumsum' được thêm vào trong phiên bản 1.12.0. Nó không hoàn toàn làm những gì bạn muốn trực tiếp mặc dù nó sẽ cho bạn kết quả '[1, 5, 6, 6, 8, 8]'. –

Trả lời

5

Làm thế nào về (mảng không-quá-lớn):

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]) 
5

Masked arrays là dành cho chỉ loại tình huống.

>>> 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]) 
7

Pandas là thư viện được xây dựng trên đầu trang numpy. Đó là Series lớp có một phương pháp cumsum, mà giữ gìn nan 's và nhanh hơn đáng kể so với các giải pháp của DSM đề xuất:

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 
+0

Ngoại trừ, tôi không làm việc với Pandas. – Benjamin