Найти - Пользователи
Полная версия: избавиться от цикла
Начало » Python для новичков » избавиться от цикла
1
math.beginer
Есть массив x_old, и нужно заменить значения этого массива на значения массива x_new. Но, из x_new можно для замены брать только те значения, которые удовлетворяют определенному условию. x_old и x_new хранят координаты точек на плоскости. Условие следующее: из x_new нужно брать только те точки, которые лежат вне эллипса с параметрами xc,yc - центр, а,b - полуоси.

Задачу решает код с циклом:
x_old=ones((m,2),dtype='d')
x_new=ndarray((m,2),dtype='d')
...
for i in range(m):
if (x_new[i][0]-xc)**2/a/a+(x_new[i][1]-yc)**2/b/b>(1.+eps):
x_old[i]=x_new[i]
от цикла хотелось бы избавиться (устраняю медленные участки). Можно ли решить задачу без цикла средствами numpy?
bw
Про numpy не знаю, но:
1. 1/a/a, 1/b/b и 1+eps можно вычислить заранее и не мучить Python в цикле.
2. Если x_new был бы традиционным списком из кортежей (про numpy не скажу, сработает ли), то: for i, (x, y) in enumerate(x_new): … (x-xc)**2 … (y-yc)…

..bw
Griffon
Или попробовать создать новый список через map(func, x_new, x_old)
n_a = 1/(a**2)
n_b = 1/(b**2)
n_c = 1.+eps
func = lambda n_new, n_old: (n_new[0]-xc)**2*n_a + (n_new[1]-yc)**2*n_b > n_c ? n_new : n_old
Или быстрее не будет?
bw
И что это такое спрашивается: … ? n_new : n_old
Тут также можно: func = lambda (n_new0, n_new1), n_old…

p.s. Про скорость сложно сказать. С одной стороны нет доступа к old по индексу (и нет всяких внутренних проверок), а с другой создаётся новый массив с добавлением за раз (?) одного элемента (не знаю как тут Python с выделением памяти работает). Нужно не гадать, а замерять скорость.

p.p.s. Для больших массивов это плохой способ.

..bw
Griffon
Ой. На плюсах сейчас пишу :)
func = lambda n_new, n_old: n_new if (n_new[0]-xc)**2*n_a + (n_new[1]-yc)**2*n_b > n_c else n_old
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB