简体   繁体   中英

Iterate through a numpy ndarray, manage first and last elements

I have a numpy array

import numpy as np
arr = np.array([2, 3, 4, 7, 7, 4, 4, 5, 1, 1, 9, 9, 9, 4, 25, 26])

I would like to iterate over this list to produce pairs of "matching" elements. In the above array, 7 matches 7. You only compare the element "ahead" and the element "behind".

My problem: how do I deal with the first and last elements?

This is what I have to begin with:

for i in range(len(arr)):
    if (arr[i] == arr[i+1]):
    print( "Match at entry %d at array location (%d)" % (arr[i], i))
else:
    pass

This outputs:

Match at entry 7 at array location (3)
Match at entry 7 at array location (4)
Match at entry 4 at array location (6)
Match at entry 1 at array location (9)
Match at entry 9 at array location (11)
Match at entry 9 at array location (12)

I feel the condition should be

 if ((arr[i] == arr[i+1]) and (arr[i] == arr[i-1]))

but this throws an error.

How do I deal with the first and last elements?

You should avoid loops in NumPy.

Using slightly modified array with pairs at the start end:

>>> arr = np.array([2, 2, 3, 4, 7, 7, 4, 4, 5, 1, 1, 9, 9, 9, 4, 25, 26, 26])

This finds the first index of each pair.

>>> np.where(arr[:-1] == arr[1:])[0]
array([ 0,  4,  6,  9, 11, 12, 16]) 

Printing them out:

arr = np.array([2, 2, 3, 4, 7, 7, 4, 4, 5, 1, 1, 9, 9, 9, 4, 25, 26, 26])
matches = np.where(arr[:-1] == arr[1:])[0] 
for index in matches:
    for i in [index, index + 1]:
        print("Match at entry %d at array location (%d)" % (arr[i], i))

prints:

Match at entry 2 at array location (0)
Match at entry 2 at array location (1)
Match at entry 7 at array location (4)
Match at entry 7 at array location (5)
Match at entry 4 at array location (6)
Match at entry 4 at array location (7)
Match at entry 1 at array location (9)
Match at entry 1 at array location (10)
Match at entry 9 at array location (11)
Match at entry 9 at array location (12)
Match at entry 9 at array location (12)
Match at entry 9 at array location (13)
Match at entry 26 at array location (16)
Match at entry 26 at array location (17)

The function np.where can be used in several ways. In our case we use the condition arr[:-1] == arr[1:] . This compares each element with the next in the array:

>>> arr[:-1] == arr[1:]
array([ True, False, False, False,  True, False,  True, False, False,
        True, False,  True,  True, False, False, False,  True], dtype=bool)

Now applying np.where to this condition gives a tuple with matching indices.

>>> cond = arr[:-1] == arr[1:]
>>> np.where(cond)
(array([ 0,  4,  6,  9, 11, 12, 16]),)

Since we have a 1D array, we get a tuple with one element. For a 2D array we would have gotten a tuple with two elements, holding the indices along the first and second dimension. We take these indices out of the tuple:

>>> np.where(cond)[0]
array([ 0,  4,  6,  9, 11, 12, 16])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM