Форум сайта python.su
Есть массив 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]
Отредактировано (Июль 14, 2011 12:53:50)
Офлайн
Про 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
Офлайн
Или попробовать создать новый список через 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)
Офлайн
И что это такое спрашивается: … ? 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)
Офлайн
Ой. На плюсах сейчас пишу :)
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
Офлайн