2012-03-06 1 views
1

Проблема 1

У меня есть четыре списка одинаковой длины: A_old, A_new, B_old, B_new и хотят иметь следующее поведение: Если A_new[i] > A_old[i] затем установите B_old[i] = B_new[i].Объединение списков на основе поэлементного состояния

Пробовал простую реализацию петлевой:

for i, (a_new, a_old) in enumerate(izip(A_new, A_old)): 
    if a_new > a_old: 
     B_old[i] = B_new[i] 

и реализацию с использованием карты (как это было предложено here):

B_old = map(lambda (a_new, a_old, b_new, b_old): b_new if a_new > a_old else b_old, 
      izip(A_new, A_old, B_new, B_old)) 

Но ни один из этих подходов достаточно быстро. Обратите внимание, что я не могу использовать массивы numpy и булевы массивы, потому что элементы B_new, B_old не являются числовыми.

Чтобы положить вещи на более формальной основе, реализация выборки представлена ​​здесь: https://gist.github.com/1986588 и рабочая среда, как показано ниже:

Naive: 1.13343191147 
Mapping: 1.45240283012 
kev: 1.09499907494 
Numpy: 0.0525879859924 
Where: 0.0651860237122 

Задача 2

Проанализировав различные варианты numpy нарезку с булевыми Кажется, что массивы - это путь. Однако я столкнулся с новой проблемой:

Пусть B_new не массив, а просто значение val. Тогда лучший вариант читает

B_old[A_new > A_old] = val 

Это прекрасно работает, пока val не итерация, но терпит неудачу, когда она есть. В частности, val является кортежем здесь. Я хотел бы назначить кортеж val элементам B_old, где A_new > A_old.

Обходной, кажется, чтобы позволить

val2 = np.empty(1, dtype=object) 
val2[0]=val 
B_old[A_new > A_old] = val 

, но это кажется запутанным. Проблема в том, что я не знаю, что такое тип val. Это может быть истребимым, и это может быть не так.

+0

Что именно вы ищете? Что вы подразумеваете под «недостаточно быстро»? – ronakg

+0

Извините, должно быть было яснее: алгоритм, над которым я работаю, вычисляет множество сверток, которые довольно дороги. Однако вышеупомянутое расходует ~ 50% вычислительных ресурсов. С другой стороны, простой «np.maximum (A_new, A_old)» потребляет едва ли какие-либо ресурсы, но имеет ту же основную форму, что и указанная выше проблема. –

+1

FWIW, вы можете использовать массивы 'numpy' для нечисловых объектов. Но я не уверен, что это ускорит все. – wim

ответ

2
B_old = [B_new[i] if A_new[i]>A_old[i] else B_old[i] for i in range(len(A_old))] 
+1

Вышеуказанное предложение, к сожалению, медленнее, чем две реализации, которые я уже пробовал. –

Смежные вопросы