Вот несколько способов ускорить ваш код Python.
Первое: Не создавайте массивы np, если вы храните только одно значение.Вы делаете это много раз в вашем коде.Например,
if firstcelltype == np.array((cellrecord[basecell,2])):
может быть просто
if firstcelltype == cellrecord[basecell,2]:
Я покажу вам почему с некоторыми утверждениями timeit:
>>> timeit.Timer('x = 111.1').timeit()
0.045882196294822819
>>> t=timeit.Timer('x = np.array(111.1)','import numpy as np').timeit()
0.55774970267830071
Это на порядок величины вразница между этими вызовами.
Второй: Следующий код:
arraytarget=round(dist*analysisdist/intervalnumber)
addone=np.array((spatialraw[arraytarget-1]))
addone=addone+1
targetcell=arraytarget-1
np.put(spatialraw,[targetcell,targetcell],addone)
можно заменить на
arraytarget=round(dist*analysisdist/intervalnumber)-1
spatialraw[arraytarget] += 1
Третий: Вы можете избавиться от площади, о которой говорил Филипп, предварительно поставив квадрат analysisdist
.Однако, поскольку вы используете analysisdist
, чтобы получить arraytarget
, вы можете создать отдельную переменную analysisdist2
, которая является квадратом анализа и использовать ее для сравнения.
Четвертое: Вы ищете ячейки, которые соответствуют secondcelltype
каждый раз, когда вы добираетесь до этой точки, вместо того, чтобы находить их один раз и использовать список снова и снова.Вы можете определить массив:
comparecells = np.where(cellrecord[:,2]==secondcelltype)[0]
и затем заменить
for comparecell in range (0, cellnumber-1):
if secondcelltype==np.array((cellrecord[comparecell,2])):
на
for comparecell in comparecells:
Пятый: Использовать psyco.Это JIT-компилятор.Matlab имеет встроенный JIT-компилятор, если вы используете несколько более позднюю версию.Это должно немного ускорить ваш код.
Шестое: Если код все еще недостаточно быстр после всех предыдущих шагов, то вам следует попробовать векторизовать ваш код.Это не должно быть слишком сложно.В основном, чем больше вещей вы можете иметь в массивах, тем лучше.Вот моя попытка векторизации:
basecells = np.where(cellrecord[:,2]==firstcelltype)[0]
xlocs = cellrecord[basecells, 0]
ylocs = cellrecord[basecells, 1]
xedgedists = xbound - xloc
yedgedists = ybound - yloc
whichcells = np.where((xlocs>excludedist) & (xedgedists>excludedist) & (ylocs>excludedist) & (yedgedists>excludedist))[0]
selectedcells = basecells[whichcells]
comparecells = np.where(cellrecord[:,2]==secondcelltype)[0]
xcomplocs = cellrecords[comparecells,0]
ycomplocs = cellrecords[comparecells,1]
analysisdist2 = analysisdist**2
for basecell in selectedcells:
dists = np.round((xcomplocs-xlocs[basecell])**2 + (ycomplocs-ylocs[basecell])**2)
whichcells = np.where((dists >= 1) & (dists <= analysisdist2))[0]
arraytargets = np.round(dists[whichcells]*analysisdist/intervalnumber) - 1
for target in arraytargets:
spatialraw[target] += 1
Вы, вероятно, можете удалить этот внутренний цикл for, но вы должны быть осторожны, потому что некоторые элементы массива могут быть одинаковыми.Кроме того, я на самом деле не опробовал весь код, так что там может быть ошибка или опечатка.Надеюсь, это даст вам хорошее представление о том, как это сделать.О, еще одна вещь.Вы делаете analysisdist/intervalnumber
отдельной переменной, чтобы избежать повторного деления.