Python is the best way to find the 1d center of mass in a numpy binary array

Suppose I have the following Numpy array in which I have one and only one continuous slice 1s:

import numpy as np
x = np.array([0,0,0,0,1,1,1,0,0,0], dtype=1)

and I want to find the 1D index of the center of mass of the elements 1. I can enter the following:

idx = np.where( x )[0]
idx_center_of_mass = int(0.5*(idx.max() + idx.min()))
# this would give 5

(Of course, this will lead to a rough approximation when the number of slice elements is 1even.) Is there a better way to do this, for example, the more efficient oneliner computational method?

+4
source share
2 answers

As one of the approaches, we can get nonzero indices and get the average of them as the center of mass, for example:

np.flatnonzero(x).mean()

, , :

np.flatnonzero(x[:-1] != x[1:]).mean()+0.5

-

In [72]: x = np.zeros(10000,dtype=int)

In [73]: x[100:2000] = 1

In [74]: %timeit np.flatnonzero(x).mean()
10000 loops, best of 3: 115 µs per loop

In [75]: %timeit np.flatnonzero(x[:-1] != x[1:]).mean()+0.5
10000 loops, best of 3: 38.7 µs per loop

, np.nonzero()[0] np.flatnonzero np.sum np.mean -

In [107]: %timeit (np.nonzero(x[:-1] != x[1:])[0].sum()+1)/2.0
10000 loops, best of 3: 30.6 µs per loop

, , , , np.mean, ,

start,stop = np.flatnonzero(x[:-1] != x[1:])
out = (stop + start + 1)/2.0

-

In [90]: %timeit start,stop = np.flatnonzero(x[:-1] != x[1:])
10000 loops, best of 3: 21.3 µs per loop

In [91]: %timeit (stop + start + 1)/2.0
100000 loops, best of 3: 4.45 µs per loop

, np.nonzero()[0] .

+2

?

center_of_mass = (x*np.arange(len(x))).sum()/x.sum() # 5

%timeit center_of_mass = (x*arange(len(x))).sum()/x.sum()
# 100000 loops, best of 3: 10.4 µs per loop
+3

Source: https://habr.com/ru/post/1655931/


All Articles