![](/img/trans.png)
[英]Replace zeros with mean of non-zeros along an axis of array - Python / NumPy
[英]efficiently finding the interval with non-zeros in scipy/numpy in Python?
假設我有一個python列表或一個python一維數組(以numpy表示)。 假設有一個連續的元素段,我怎樣才能找到這個列表或數組中非零段的開始和結束坐標(即索引)? 例如,
a = [0, 0, 0, 0, 1, 2, 3, 4]
nonzero_coords(a)應該返回[4,7]。 對於:
b = [1, 2, 3, 4, 0, 0]
nonzero_coords(b)應返回[0,2]。
謝謝。
假設有一個連續的非零元素......
x = nonzero(a)[0]
result = [x[0], x[-1]]
這適用於我的多個洞
from numpy import *
def nonzero_intervals(value):
lvalue = array(value)
lvalue[0] = 0
lvalue[-1] = 0
a = diff((lvalue==0) * 1)
intervals = zip( find(a == -1),find(a == 1))
return intervals
實際上,nonzero_coords(b)應該返回[0,3]。 輸入端可能出現多個孔嗎? 如果是,那該怎么辦? 天真的解決方案:掃描直到第一個非零el。 然后掃描直到最后一個非零el。 代碼如下(抱歉沒有測試):
a = [0, 0, 0, 0, 1, 2, 3, 4, 5, 0, 0, 0]
start = 0
size = len(a) #
while (start < size and a[start] != 0): start += 1
end = start
while (end < size and a[end] != 0): end += 1
return (start, end)
對於nonzero_coords([0, 0, 0, 0, 1, 2, 3, 4])
返回(4, 8)
不是(4, 7)
nonzero_coords([0, 0, 0, 0, 1, 2, 3, 4])
,python索引會更加一致,因為[0, 0, 0, 0, 1, 2, 3, 4][4:8]
返回[1, 2, 3, 4]
。
這是一個計算非零間隔的函數。 它處理多個間隔:
def nonzero_intervals(vec):
'''
Find islands of non-zeros in the vector vec
'''
if len(vec)==0:
return []
elif not isinstance(vec, np.ndarray):
vec = np.array(vec)
edges, = np.nonzero(np.diff((vec==0)*1))
edge_vec = [edges+1]
if vec[0] != 0:
edge_vec.insert(0, [0])
if vec[-1] != 0:
edge_vec.append([len(vec)])
edges = np.concatenate(edge_vec)
return zip(edges[::2], edges[1::2])
如果你真的希望答案在島上包含結束索引,你可以將最后一行更改為: return zip(edges[::2], edges[1::2]-1)
測試:
a = [0, 0, 0, 0, 1, 2, 3, 4]
intervals = nonzero_intervals(a)
assert intervals == [(4, 8)]
a = [1, 2, 3, 4, 0, 0]
intervals = nonzero_intervals(a)
assert intervals == [(0, 4)]
a=[1, 2, 0, 0, 0, 3, 4, 0]
intervals = nonzero_intervals(a)
assert intervals == [(0, 2), (5, 7)]
a = [0, 4, 0, 6, 0, 6, 7, 0, 9]
intervals = nonzero_intervals(a)
assert intervals == [(1, 2), (3, 4), (5, 7), (8, 9)]
a = [1, 2, 3, 4]
intervals = nonzero_intervals(a)
assert intervals == [(0, 4)]
a = [0, 0, 0]
intervals = nonzero_intervals(a)
assert intervals == []
a = []
intervals = nonzero_intervals(a)
assert intervals == []
如果你還是裝了numpy,請選擇tom10的答案。
如果由於某種原因你想要的東西沒有加載numpy(無法想象為什么,說實話),那么我建議這樣的事情:
from itertools import groupby
def nonzero_coords(iterable):
start = 0
for iszero, sublist in groupby(iterable, lambda x:x==0):
if iszero:
start += len(list(sublist))
else:
return start, start+len(list(sublist))-1
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.