简体   繁体   English

在Python中有效地找到scipy / numpy中非零的间隔?

[英]efficiently finding the interval with non-zeros in scipy/numpy in Python?

suppose I have a python list or a python 1-d array (represented in numpy). 假设我有一个python列表或一个python一维数组(以numpy表示)。 assume that there is a contiguous stretch of elements how can I find the start and end coordinates (ie indices) of the stretch of non-zeros in this list or array? 假设有一个连续的元素段,我怎样才能找到这个列表或数组中非零段的开始和结束坐标(即索引)? for example, 例如,

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

nonzero_coords(a) should return [4, 7]. nonzero_coords(a)应该返回[4,7]。 for: 对于:

b = [1, 2, 3, 4, 0, 0]

nonzero_coords(b) should return [0, 2]. nonzero_coords(b)应返回[0,2]。

thanks. 谢谢。

Assuming there's a single continuous stretch of nonzero elements... 假设有一个连续的非零元素......

x = nonzero(a)[0]
result = [x[0], x[-1]]

This worked for multiple holes for me 这适用于我的多个洞

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

Actually, nonzero_coords(b) should return [0, 3]. 实际上,nonzero_coords(b)应该返回[0,3]。 Can multiple holes occur at the input? 输入端可能出现多个孔吗? If yes, what to do then? 如果是,那该怎么办? The naive solution: scan until first non-zero el. 天真的解决方案:扫描直到第一个非零el。 Then scan until the last non-zero el. 然后扫描直到最后一个非零el。 Code is below (sorry did not test it): 代码如下(抱歉没有测试):

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)

It would be more consistent with python indexing for nonzero_coords([0, 0, 0, 0, 1, 2, 3, 4]) to return (4, 8) than (4, 7) , because [0, 0, 0, 0, 1, 2, 3, 4][4:8] returns [1, 2, 3, 4] . 对于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]

Here is a function that computes non-zero intervals. 这是一个计算非零间隔的函数。 It handles multiple intervals: 它处理多个间隔:

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

If you really want the answer to have the end indices included in the island, you can just change the last line to: return zip(edges[::2], edges[1::2]-1) 如果你真的希望答案在岛上包含结束索引,你可以将最后一行更改为: return zip(edges[::2], edges[1::2]-1)

Tests: 测试:

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 == []

If you've got numpy loaded anyway, go with tom10's answer. 如果你还是装了numpy,请选择tom10的答案。

If for some reason you want something that works without loading numpy (can't imagine why, to be honest) then I'd suggest something like this: 如果由于某种原因你想要的东西没有加载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.

相关问题 用沿数组轴的非零均值替换零 - Python / NumPy - Replace zeros with mean of non-zeros along an axis of array - Python / NumPy Python Scipy如何从csr_matrix遍历上/下三角部分非零 - Python Scipy How to traverse upper/lower trianglar portion non-zeros from csr_matrix 在SciPy / NumPy中查找复杂函数的零 - Finding zeros of a complex function in SciPy/NumPy 如何添加只填充零而不影响 Python OpenCV 中的非零 - How to add such that only zeros are filled leaving non-zeros unaffected in Python OpenCV 如何在Keras的数组中找到非零的数量? - How to find the number of non-zeros in an array in Keras? 如何提取具有非零列值的行? - How to extract rows with non-zeros column values? 寻找非线性方程python scipy - finding non linear equation python scipy 使用numpy / scipy在python中均匀高效地采样整数 - sampling integers uniformly efficiently in python using numpy/scipy 计算沿行和列连接的非零点的数量,但不计算 shell 脚本中矩阵中的对角线 - Count the number of connected non-zeros along rows and columns but not diagonaly in a Matrix in shell script 在Python / Numpy / Scipy中找到两个数组之间的插值交点 - finding the interpolated intersection between two arrays in Python/Numpy/Scipy
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM