Как расширить массив пустышек

У меня есть массив точек с формой (1000,3) где ось 1 принимает значения [x,y,1]

Точки имеют дискретные значения в сетке, поэтому примерный массив выглядит так:

array=([1,2,1],[4,5,1],[2,3,1],...,[xN,yN,1])

Я хотел бы расширить этот 2d массив, и под этим я подразумеваю, для каждого [x,y,1] координата в массиве, если [x±1,y±1,1] не в массиве добавить его в массив.

В настоящее время я делаю это с помощью следующего кода:

np.append(array, [array[:,0],array[:,1]+1,1])
np.append(array, [array[:,0]+1,array[:,1],1])
np.append(array, [array[:,0]+1,array[:,1]+1,1])
np.append(array, [array[:,0]-1,array[:,1],1])
np.append(array, [array[:,0],array[:,1]-1,1])
np.append(array, [array[:,0]-1,array[:,1]-1,1])
np.append(array, [array[:,0]+1,array[:,1]-1,1])
np.append(array, [array[:,0]-1,array[:,1]+1,1])

тогда я использую np.unique(array) сократить до неузнаваемости элементов. Этот метод работает, но он слишком медленный, чтобы работать на больших массивах с более чем 100000 точек, и это не похоже на гладкое решение. Должен быть способ сделать это, не дублируя столько точек, чтобы найти все уникальные экземпляры. Есть ли другой (читай: быстрее) способ сделать то, что я делаю?

1 ответ

Решение

2000 x 4000 x 200 это просто выполнимо с таблицей поиска. Чуть ниже миллиона координат я получаю ускорение в ~5 раз по сравнению с np.unique подход.

lookup table:  2.18715, np.unique: 11.40247

Код:

import numpy as np
from numpy.lib.stride_tricks import as_strided
from time import time

coords = np.unique(np.random.randint(0, 2000*4000*200, (1000000,)))
coords = np.c_[coords // (4000*200), (coords // 200) % 4000, coords % 200]

t = [time()]

ws = np.empty((2002, 4002, 202), dtype=np.uint8)
ws = as_strided(ws, (2000, 4000, 200, 3, 3, 3), 2 * ws.strides)

ws[tuple(coords.T)] = np.arange(27).reshape(3, 3, 3)
unq = ws[tuple(coords.T)] == np.arange(27).reshape(3, 3, 3)
result = (coords[:, None, None, None, :] + np.moveaxis(np.indices((3, 3, 3)) - 1, 0, -1))[unq]
del ws

t.append(time())

result2 = np.unique((coords[:, None, None, None, :] + np.moveaxis(np.indices((3, 3, 3)) - 1, 0, -1)).reshape(-1, 3), axis = 0)

t.append(time())

print('lookup table: {:8.5f}, np.unique: {:8.5f}'.format(*np.diff(t)))
Другие вопросы по тегам