Мы проверяем, находятся ли эти числа с плавающей точкой в pts
в каждом целочисленном бине на каждой итерации.Итак, хитрость, которую мы могли бы использовать, - преобразовать эти числа с плавающей точкой в их числа с плавающей точкой.Кроме того, нам нужно замаскировать действительные, которые удовлетворяют range(M)
и range(N)
.Вот и все!
Вот реализация -
def binpts(pts, M, K):
N = len(pts)
in_bin_out = np.zeros((M, K, N), dtype=bool)
mask = (pts[:,0]<M) & (pts[:,1]<K)
pts_f = pts[mask]
r,c = pts_f.astype(int).T
in_bin_out[r, c, mask] = 1
return in_bin_out
Сравнительный анализ
Синхронизация больших массивов с диапазоном в массиве плавающих pts, пропорциональным его размерукак указано в данном примере -
Случай № 1:
In [2]: M = 100
...: K = 101
...: N = 10000
...: np.random.seed(0)
...: pts = 2000 * np.random.rand(N, 2)
# @hpaulj's soln
In [3]: %%timeit
...: x0=(pts[:,0]>=np.arange(M)[:,None]) & (pts[:,0]<np.arange(1,M+1)[:,None])
...: x1=(pts[:,1]>=np.arange(K)[:,None]) & (pts[:,1]<np.arange(1,K+1)[:,None])
...: xx = x0[:,None,:] & x1[None,:,:]
10 loops, best of 3: 47.5 ms per loop
# @user545424's soln
In [6]: %timeit bin_points(pts,M,K)
1000 loops, best of 3: 331 µs per loop
In [7]: %timeit binpts(pts,M,K)
10000 loops, best of 3: 125 µs per loop
Примечание: Soln @ hpaulj требует большого объема памяти, и у меня закончилась память, используя его на более крупных.
Дело № 2:
In [8]: M = 100
...: K = 101
...: N = 100000
...: np.random.seed(0)
...: pts = 20000 * np.random.rand(N, 2)
In [9]: %timeit bin_points(pts,M,K)
...: %timeit binpts(pts,M,K)
100 loops, best of 3: 2.31 ms per loop
1000 loops, best of 3: 585 µs per loop
Дело № 3:
In [10]: M = 100
...: K = 101
...: N = 1000000
...: np.random.seed(0)
...: pts = 200000 * np.random.rand(N, 2)
In [11]: %timeit bin_points(pts,M,K)
...: %timeit binpts(pts,M,K)
10 loops, best of 3: 34.6 ms per loop
100 loops, best of 3: 2.78 ms per loop