Уведомления

Группа в Telegram: @pythonsu

#1 Июль 14, 2011 12:53:00

math.beginer
От:
Зарегистрирован: 2011-03-28
Сообщения: 40
Репутация: +  0  -
Профиль   Отправить e-mail  

избавиться от цикла

Есть массив 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?



Отредактировано (Июль 14, 2011 12:53:50)

Офлайн

#2 Июль 14, 2011 13:17:26

bw
От:
Зарегистрирован: 2007-09-26
Сообщения: 938
Репутация: +  20  -
Профиль   Адрес электронной почты  

избавиться от цикла

Про 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



Офлайн

#3 Июль 14, 2011 16:25:14

Griffon
От: Ukrain, Zaporozhie
Зарегистрирован: 2009-03-04
Сообщения: 324
Репутация: +  11  -
Профиль   Отправить e-mail  

избавиться от цикла

Или попробовать создать новый список через 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
Или быстрее не будет?



Отредактировано (Июль 14, 2011 16:34:59)

Офлайн

#4 Июль 14, 2011 16:44:29

bw
От:
Зарегистрирован: 2007-09-26
Сообщения: 938
Репутация: +  20  -
Профиль   Адрес электронной почты  

избавиться от цикла

И что это такое спрашивается: … ? n_new : n_old
Тут также можно: func = lambda (n_new0, n_new1), n_old…

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

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

..bw



Отредактировано (Июль 14, 2011 16:48:20)

Офлайн

#5 Июль 14, 2011 16:51:20

Griffon
От: Ukrain, Zaporozhie
Зарегистрирован: 2009-03-04
Сообщения: 324
Репутация: +  11  -
Профиль   Отправить e-mail  

избавиться от цикла

Ой. На плюсах сейчас пишу :)

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



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version