Home > front end >  Numpy Sum Array Coordinates to Array efficiently
Numpy Sum Array Coordinates to Array efficiently

Time:12-26

Given an Array of Points

points = np.array([[1,1,1], [0,1,1], [1,0,0], [1,1,1]])

create an array that counts the coordinates, meaning:

r = [[0,0],  [[1,0],
     [0,1]],  [0,2]]

meaning the coordinate [1,1,1] exists twice so a the position [1,1,1] there is a 2 in the resulting array.

In plain python this would be:

for p in points:
    r[p[0]][p[1]][p[2]]  = 1

I need this in the context of an realtime application, there are up to 300k points given per frame and a resulting matrix shape of up to 400x400x400, so speed is important. the amount of points and shape of the resulting matrix change dynamically.

I am new to numpy and have not found an efficient way to do this, doing it with a plain python for loop is too slow taking up to a second per frame.

CodePudding user response:

Consider the following.

points = np.array([[1,1,1], [0,1,1], [1,0,0], [1,1,1]])

unique, counts = np.unique(points, return_counts = True, axis = 0)
n = 1 np.max(unique)
r = np.zeros([n,n,n], dtype = int)
r[tuple(unique.T)] = counts

(Note: the final line above is equivalent to r[unique[:,0],unique[:,1],unique[:,2]] = counts).

Resulting array r:

[[[0 0]
  [0 1]]

 [[1 0]
  [0 2]]]

CodePudding user response:

You can ravel the 3D coordinates to 1D offsets with np.ravel_multi_index and count these using np.bincount.

import numpy as np

points = np.array([[1,1,1], [0,1,1], [1,0,0], [1,1,1]])

m = points.max(0) 1
np.bincount(np.ravel_multi_index(points.T, m), minlength=np.prod(m)).reshape(m)

Output

array([[[0, 0],
        [0, 1]],

       [[1, 0],
        [0, 2]]])
  • Related