Как frompyfunc перебирает массивы? - PullRequest
0 голосов
/ 30 октября 2018

Я работаю с большими массивами, представляющими сетку маршрутизации лабиринта, каждый элемент является объектом Cell с атрибутами x, y.

Я пытаюсь использовать numpyfunc для инициализации координат в каждой ячейке с помощью векторизованной функции.

У меня есть векторизованная функция, которая устанавливает координату X объекта Cell:

def setCellX(self,c,x):
         c.setX(x)
         return c

setCellX_v = np.vectorize(self.setCellX)

Я заключаю это в frompyfunc

setCellX_npfunc = np.frompyfunc(self.setCellX_v,2,1)

Когда я вызываю это для 1-D массива, он работает как положено

Gx = 3000
Gy = 4000

# Initialize single row
R = np.array([Cell(0,y) for y in range(int(self.Gy))])

# Create array of X-coordinates
x_indices = [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19]

print R[6].x
0

setCellX_npfunc(R,x_indices)
print R[6].x
6

Когда я устанавливаю R в качестве двумерного массива, я ожидаю, что numpyfunc будет перебирать каждую строку и соответственно устанавливать значения X:

R = np.empty(shape=(20,20),dtype=object)
R.fill(Cell(0,0))

setCellX_npfunc(R,x_indices)
print(R[3][6].x)
19

Почему бы numpyfunc не установить значения X для каждого 1-го вектора на соответствующее значение в x_indices, как это было в первом примере?

1 Ответ

0 голосов
/ 30 октября 2018

Исходя из ваших комментариев и предположим, что Cell объекты имеют атрибуты x, y и некоторые другие атрибуты по умолчанию, которые не воспроизводятся:

class Cell:
    def __init__(self, x,y):
        self.x = x
        self.y = y
    ...

Предположим, вы хотите массив 100 * 100, запустите ваш массив следующим образом:

CellList = [[Cell(x,y) for y in range(100)] for x in range(100)]
# Optional translate it into np.array for easier indexing
CellArr = np.array(CellList)

Это вернет ваш массив ячеек 100 * 100 с правильными элементами ячейки. Для проверки:

CellArr[1,2].x
>>> 1

Обратите внимание, что numpy не может на самом деле сильно ускорить ваш массив, потому что Cell не может на самом деле проходить код C при векторизации. Его можно использовать только для лучшей индексации.

Векторизация на самом деле не помогает вашей скорости:

%%timeit
CellList = [[Cell(x,y) for y in range(100)] for x in range(100)]
# Optional translate it into np.array for easier indexing
CellArr = np.array(CellList)

>>> 24.2 ms ± 542 µs per loop

Функции векторизации:

def vecX(c, x):
    c = Cell(x, 0)
    return c

def vecY(c, y):
    c.y = y
    return c

vec = np.vectorize(vecX)
vey = np.vectorize(vecY)

Результаты:

%%timeit
l = []
n = np.zeros((100,100))
for i in range(len(n)):
    l.append(vec(n[i, :], i))
CellArr = np.vstack(l)
for j in range(len(CellArr)):
    vey(CellArr[:, j], j)

>>> 23.5 ms ± 5 ms per loop 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...