Find indexes of repeated elements in an array (Python, NumPy)

前端 未结 5 1226
甜味超标
甜味超标 2020-12-20 14:52

Assume, I have a NumPy-array of integers, as:

[34,2,3,22,22,22,22,22,22,18,90,5,-55,-19,22,6,6,6,6,6,6,6,6,23,53,1,5,-42,82]

I want to find

5条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-12-20 15:25

    Here is a solution using Python's native itertools.

    Code

    import itertools as it
    
    
    def find_ranges(lst, n=2):
        """Return ranges for `n` or more repeated values."""
        groups = ((k, tuple(g)) for k, g in it.groupby(enumerate(lst), lambda x: x[-1]))
        repeated = (idx_g for k, idx_g in groups if len(idx_g) >=n)
        return ((sub[0][0], sub[-1][0]) for sub in repeated)
    
    lst = [34,2,3,22,22,22,22,22,22,18,90,5,-55,-19,22,6,6,6,6,6,6,6,6,23,53,1,5,-42,82]    
    list(find_ranges(lst, 5))
    # [(3, 8), (15, 22)]
    

    Tests

    import nose.tools as nt
    
    
    def test_ranges(f):
        """Verify list results identifying ranges."""
        nt.eq_(list(f([])), [])
        nt.eq_(list(f([0, 1,1,1,1,1,1, 2], 5)), [(1, 6)])
        nt.eq_(list(f([1,1,1,1,1,1, 2,2, 1, 3, 1,1,1,1,1,1], 5)), [(0, 5), (10, 15)])
        nt.eq_(list(f([1,1, 2, 1,1,1,1, 2, 1,1,1], 3)), [(3, 6), (8, 10)])    
        nt.eq_(list(f([1,1,1,1, 2, 1,1,1, 2, 1,1,1,1], 3)), [(0, 3), (5, 7), (9, 12)])
    
    test_ranges(find_ranges)
    

    This example captures (index, element) pairs in lst, and then groups them by element. Only repeated pairs are retained. Finally, first and last pairs are sliced, yielding (start, end) indices from each repeated group.

    See also this post for finding ranges of indices using itertools.groupby.

提交回复
热议问题