Dưới đây là một việc thực hiện vectorized khá nhỏ gọn. Tôi đã thay đổi các yêu cầu một chút, vì vậy giá trị trả về là "bit" một chút: nó tạo ra một mảng có hình dạng (m, 2), trong đó m là số "chạy" của số không. Cột đầu tiên là chỉ số của 0 đầu tiên trong mỗi lần chạy và cột thứ hai là chỉ mục của phần tử nonzero đầu tiên sau khi chạy. (Mô hình lập chỉ mục này phù hợp, ví dụ, làm thế nào cắt công trình và làm thế nào range
chức năng hoạt động.)
import numpy as np
def zero_runs(a):
# Create an array that is 1 where a is 0, and pad each end with an extra 0.
iszero = np.concatenate(([0], np.equal(a, 0).view(np.int8), [0]))
absdiff = np.abs(np.diff(iszero))
# Runs start and end where absdiff is 1.
ranges = np.where(absdiff == 1)[0].reshape(-1, 2)
return ranges
Ví dụ:
In [236]: a = [1, 2, 3, 0, 0, 0, 0, 0, 0, 4, 5, 6, 0, 0, 0, 0, 9, 8, 7, 0, 10, 11]
In [237]: runs = zero_runs(a)
In [238]: runs
Out[238]:
array([[ 3, 9],
[12, 16],
[19, 20]])
Với định dạng này, nó rất đơn giản để có được số lượng các zeros trong mỗi lần chạy:
In [239]: runs[:,1] - runs[:,0]
Out[239]: array([6, 4, 1])
Nó luôn luôn là một ý tưởng tốt để kiểm tra các trường hợp cạnh:
In [240]: zero_runs([0,1,2])
Out[240]: array([[0, 1]])
In [241]: zero_runs([1,2,0])
Out[241]: array([[2, 3]])
In [242]: zero_runs([1,2,3])
Out[242]: array([], shape=(0, 2), dtype=int64)
In [243]: zero_runs([0,0,0])
Out[243]: array([[0, 3]])
Tại sao bỏ phiếu, Xin hãy viết lại hồ sơ – Shan
Không phải tôi, nhưng nó là truyền thống để nói điều gì đó như "Tôi có mã này" (và hiển thị nó) và nó không hoạt động. Bạn đã không hiển thị những gì bạn đã thử. – doctorlove
tốt, tôi chỉ có thể đi qua mảng với một vòng lặp và đánh dấu các chỉ số bắt đầu và kết thúc, tôi nghĩ rằng những người biết python sẽ hiểu nó dễ dàng – Shan