Объединение 2D-данных в перекрывающиеся круги по x, y - PullRequest
0 голосов
/ 22 января 2019

В настоящее время я работаю с довольно большим набором данных трехмерных точек (x, y, z) и хотел бы найти эффективное средство для определения того, какие точки находятся внутри набора окружностей в плоскости xy с радиусом r и центром ( x1, y1), где x1 и y1 - координаты сетки (длиной 120 каждая). Круги будут перекрываться, а некоторые точки будут принадлежать нескольким кругам.

Таким образом, на выходе должны быть тождества 14400 кружков (120 * 120), и какие точки в списке (x, y, z) находятся в каждом.

import numpy as np

def inside_circle(x, y, x0, y0, r):
    return (x - x0)*(x - x0) + (y - y0)*(y - y0) < r*r

x = np.random.random_sample((10000,))
y = np.random.random_sample((10000,))

x0 = np.linspace(min(x),max(x),120)
y0 = np.linspace(min(y),max(y),120)

idx = np.zeros((14400,10000))
r = 2
count = 0

for i in range(0,120):
    for j in range(0,120):
        idx[count,:] = inside_circle(x,y,x0[i],y0[j],r)
        count = count + 1

где inside_circle - это функция, которая выдает массив логических значений True или False для каждой тестируемой точки x, y, z в круге радиуса r с центром x0 [i] и x0 [j]

Мой главный вопрос: есть ли более эффективный способ сделать это, чем вложенный цикл for? Или даже более эффективный способ сделать что-нибудь здесь вообще - поскольку я довольно плохо знаком с python.

Спасибо за любые ответы!

Алек.

1 Ответ

0 голосов
/ 23 января 2019

Этот использует широковещательную рассылку и работает немного быстрее, чем вложенные циклы for (0,5 с против 0,8 с на моей машине). На мой взгляд, читаемость снизилась.

import numpy as np

x = np.random.random_sample((1, 10000))
y = np.random.random_sample((1, 10000))

x0 = np.reshape(np.linspace(np.min(x),np.max(x),120), (120, 1))
y0 = np.reshape(np.linspace(np.min(y),np.max(y),120), (120, 1))

r = 2

all_xdiffssquared = np.subtract(x, x0)**2
all_ydiffssquared = np.subtract(y, y0)**2
# 3d here means that the array has 3 dimensions. Not the geometry described
all_xdiffssquared_3d = np.reshape(all_xdiffssquared, (120, 10000, 1))
all_ydiffssquared_3d = np.reshape(np.transpose(all_ydiffssquared), (1, 10000, 120))
all_distances_3d = all_xdiffssquared_3d + all_ydiffssquared_3d - r**2
idx = np.signbit(np.reshape(np.moveaxis(all_distances_3d, 1, -1), (14400, 10000)))
...