Я довольно новичок в Python, но я начал использовать его для некоторого анализа данных, и теперь мне это нравится. Раньше я использовал C, который я считаю просто ужасным для ввода-вывода файлов.Python: оптимизация цикла
Я работаю над скриптом, который вычисляет radial distribution function между множеством N = 10000 (десять тысяч) точек в трехмерном поле с периодическими граничными условиями (PBC). В принципе, у меня есть файл из 10000 строк, выполненных так:
0.037827 0.127853 -0.481895
12.056849 -12.100216 1.607448
10.594823 1.937731 -9.527205
-5.333775 -2.345856 -9.217283
-5.772468 -10.625633 13.097802
-5.290887 12.135528 -0.143371
0.250986 7.155687 2.813220
который представляет координаты N точек. Я должен вычислить расстояние между каждыми двумя точками (поэтому я должен рассмотреть все комбинации из 49995000 из 2 элементов), а затем выполнить некоторую операцию над ним.
Конечно, наиболее облагаемая налогом часть программы представляет собой цикл по комбинациям 49995000.
Моя текущая функция выглядит следующим образом:
g=[0 for i in range(Nbins)]
for i in range(Nparticles):
for j in range(i+1,Nparticles):
#compute distance and apply PBC
dx=coors[i][0]-coors[j][0]
if(dx>halfSide):
dx-=boxSide
elif(dx<-halfSide):
dx+=boxSide
dy=coors[i][1]-coors[j][1]
if(dy>halfSide):
dy-=boxSide
elif(dy<-halfSide):
dy+=boxSide
dz=coors[i][2]-coors[j][2]
if(dz>halfSide):
dz-=boxSide
elif(dz<-halfSide):
dz+=boxSide
d2=dx**2+dy**2+dz**2
if(d2<(cutoff*boxSide)**2):
g[int(sqrt(d2)/dr)]+=2
Примечание: coors
вложенный массив, созданный с помощью loadtxt()
на файл данных.
Я в основном переработаны функции, которые я использовал в другой программе, написанной на C.
Я не использую itertool.combinations()
, потому что я заметил, что программа работает немного медленнее, если я использую его по какой-то причине (одна итерация около 111 с, пока он работает около 106 с этой реализацией).
Эта функция занимает около 106 с, что ужасно, учитывая, что мне приходится анализировать около 500 конфигурационных файлов.
Теперь, мой вопрос:: Есть ли общий способ сделать такие циклы быстрее работать с помощью Python? Я предполагаю, что соответствующий C-код будет быстрее, но я хотел бы придерживаться Python, потому что он намного проще в использовании.
Я хотел бы подчеркнуть, что хотя я и ищу конкретное решение моей проблемы, я хотел бы знать, как более эффективно выполнять итерацию при использовании Python в целом.
PS Пожалуйста, постарайтесь как можно больше объяснить код в своих ответах (если вы напишите), потому что я новичок в Python.
Update
Во-первых, я хочу сказать, что я знаю, что, так как есть обрезание, я мог бы написать более эффективный алгоритм, если я разделить окно в небольших коробках и только вычислить расстояния в соседних но на данный момент мне хотелось бы ускорить этот конкретный алгоритм.
Я также хочу сказать, что с помощью Cython (я следил за этим tutorial) мне удалось немного ускорить все, как ожидалось (77 с, где до этого было 106).
Если вы используете python2.x, вы захотите использовать 'xrange', а не' range'. Если это не будет достаточно быстро, вам, вероятно, придется начать использовать что-то вроде «numpy» и выяснить, как вы можете выполнять операции с помощью векторизованных функций numpy. – mgilson
Вам абсолютно нужно использовать вложенные для петель? обычно это запах кода, и его следует избегать –
Если numpy или pandas не ускоряют работу, Python также позволяет вам выполнять код C - вы также можете проверить это. – 7stud