2013-10-16 41 views
8

Tôi có một mảng NumPy:Vary các yếu tố trong một mảng NumPy

a = [3., 0., 4., 2., 0., 0., 0.] 

Tôi muốn một mảng mới, được tạo ra từ này, nơi không yếu tố không được chuyển đổi thành giá trị của họ trong số không và không yếu tố này là được chuyển đổi thành một số duy nhất bằng số lượng số không liên tiếp tức là:

b = [0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 3.] 

Tìm cách vector hóa làm mảng này sẽ có> 1 triệu phần tử. Bất kỳ trợ giúp nào được đánh giá cao.

+0

Tôi sẽ ngạc nhiên nếu điều này có thể được vector hóa nhưng chúc may mắn :) – Hammer

Trả lời

8

Điều này cần thực hiện thủ thuật, nó hoạt động bằng 1) tìm tất cả các số 0 liên tiếp và đếm chúng, 2) tính toán kích thước của mảng đầu ra và khởi tạo nó bằng số không, 3) đặt số đếm từ phần 1 trong địa điểm chính xác.

def cz(a): 
    a = np.asarray(a, int) 

    # Find where sequences of zeros start and end 
    wz = np.zeros(len(a) + 2, dtype=bool) 
    wz[1:-1] = a == 0 
    change = wz[1:] != wz[:-1] 
    edges = np.where(change)[0] 
    # Take the difference to get the number of zeros in each sequence 
    consecutive_zeros = edges[1::2] - edges[::2] 

    # Figure out where to put consecutive_zeros 
    idx = a.cumsum() 
    n = idx[-1] if len(idx) > 0 else 0 
    idx = idx[edges[::2]] 
    idx += np.arange(len(idx)) 

    # Create output array and populate with values for consecutive_zeros 
    out = np.zeros(len(consecutive_zeros) + n) 
    out[idx] = consecutive_zeros 
    return out 
+0

Tuyệt vời, hoạt động rất tốt. Đơn đặt hàng của magnitudes nhanh hơn so với các vòng tôi đã cố gắng sử dụng. – tommw

4

Đối với một số loại:

a = np.array([3., 0., 4., 2., 0., 0., 0.],dtype=np.int) 

inds = np.cumsum(a) 

#Find first occurrences and values thereof. 
uvals,zero_pos = np.unique(inds,return_index=True) 
zero_pos = np.hstack((zero_pos,a.shape[0]))+1 

#Gets zero lengths 
values = np.diff(zero_pos)-1 
mask = (uvals!=0) 

#Ignore where we have consecutive values 
zero_inds = uvals[mask] 
zero_inds += np.arange(zero_inds.shape[0]) 

#Create output array and apply zero values 
out = np.zeros(inds[-1] + zero_inds.shape[0]) 
out[zero_inds] = values[mask] 

out 
[ 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 3.] 

Chủ yếu là thay đổi trong thực tế là chúng ta có thể sử dụng np.unique để tìm lần xuất hiện đầu tiên của một mảng miễn là nó được đơn điệu tăng.

+0

Câu trả lời hay. Tôi nghĩ rằng đó là một chút tắt nếu một có 0 hàng đầu, nhưng điều đó sẽ dễ dàng để sửa chữa. –

+0

Cả hai đều tốt đẹp, @ BiRico vẫn còn nhanh hơn một chút trên máy tính của tôi. – askewchan

+0

@BiRico Điểm tốt, thiếu khía cạnh đó. Điều thú vị là bạn cần các giá trị lớn trong mảng của bạn ('a> 300') trước khi phương thức này trở nên nhanh hơn. – Daniel

Các vấn đề liên quan