1

I am currently trying for a data series such as:

a = np.array([0,0,0,8,13,12,5,0,0,05,6,8,14,0,0,0]) 

To get the centroid of each number collective between the zeros as well as their position in the array. Here, the position is more important to me - I have yet to find a good approach to this.

Skully
  • 2,882
  • 3
  • 20
  • 31
  • What do you mean by "each number collective between the zeros"? Can you give an example? – Gderu Nov 18 '21 at 11:26
  • Thank you for your reply. For example a number collective here would be 8,13,12,5. so the centroid would be at the position of the number 13. The second number collective wuold be 5,6,8,14, the centroid here would be 8. Something like 50% of the cumulated value of the numbers between the zeros. Hope i could explain it well enough – Spartak Goga Nov 18 '21 at 11:52
  • Please read https://stackoverflow.com/questions/70012889/what-is-a-faster-way-to-get-the-center-points-of-objects-represented-in-a-2d-n . This is basically the exact same question but in 2D (posted today like similar other questions). – Jérôme Richard Nov 18 '21 at 13:23

1 Answers1

0

You can do the following:

  • Find indices of nonzero items:

    arr = np.array([0,0,0,8,13,12,5,0,0,0,5,6,8,14,0,0,0])
    idx = np.flatnonzero(x!=0)
    >>> idx
    array([ 3,  4,  5,  6, 10, 11, 12, 13], dtype=int64)
    
  • Find the bounding ones:

    starting_idx = idx[np.diff(idx, prepend=idx[0])!=1]
    ending_idx = idx[np.diff(idx, append=idx[-1])!=1]
    bounding_idx = np.transpose([starting_idx, ending_idx])
    >>> bounding_idx
    array([[ 3,  6], [10, 13]], dtype=int64)
    
  • Get indices of centroid candidates:

    c = np.mean(bounding_idx, axis=1)
    c1 = np.floor(c).astype(int)
    c2 = np.ceil(c).astype(int)
    candidate_idx = np.transpose([c1, c2])
    >>> candidate_idx
    array([[ 4,  5], [11, 12]])
    
  • Find candidates itself:

    candidates = arr[np.ravel(candidate_idx)].reshape(-1,2)
    >>> candidates
    array([[13, 12], [ 6,  8]])
    
  • Find indices of candidates that correspond to centroids:

    centroid_idx = np.argmax(candidates, axis=1)
    >>> centroid_idx
    array([0, 1], dtype=int64)
    
  • Finally, get centroids and their indices:

    >>> candidates[np.arange(len(candidates)), centroid_idx]
    array([13,  8])
    >>> candidate_idx[np.arange(len(candidate_idx)), centroid_idx]
    array([ 4, 12])
    
mathfux
  • 5,759
  • 1
  • 14
  • 34