Средневзвешенное по элементам между двумя массивами - PullRequest
2 голосов
/ 27 мая 2019

У меня есть два массива чисел, и я хочу вычислить средневзвешенное значение по элементам между этими массивами и сохранить его в новом массиве.

Решение, которое я сейчас использую:

array_1 = [0,1,2,3,4]
array_2 = [2,3,4,5,6]

weight_1 = 0.5
weight_2 = 0.5

array_3 = np.zeros(array_1.shape)

for i in range(0, len(array_1)) : 
    array_3[i] = np.average(a=[array_1[i], array_2[i]], weights=[weight_1, weight_2])

print(array_3)
>> [1,2,3,4,5]

Проблема в том, что это не очень эффективно.Как я могу сделать это более эффективно?

Ответы [ 3 ]

3 голосов
/ 27 мая 2019

Вы можете zip оба итератора и умножить каждый элемент на соответствующий вес

array_1 = [0,1,2,3,4]
array_2 = [2,3,4,5,6]

weight_1 = 0.5
weight_2 = 0.5

#Zip both iterators and multiply weight with corresponding item
result = [ item1 * weight_1 + item2 * weight_2 for item1, item2 in zip(array_1, array_2)]
print(result)

Выход будет

[1.0, 2.0, 3.0, 4.0, 5.0]
2 голосов
/ 27 мая 2019

Просто используйте векторизованные операции NumPy. Для этого сначала преобразуйте свои списки в массивы, а затем просто умножьте каждый массив на соответствующий вес и возьмите сумму

import numpy as np

array_1 = np.array([0,1,2,3,4])
array_2 = np.array([2,3,4,5,6])

weight_1 = 0.5
weight_2 = 0.5

array_3 = weight_1*array_1 + weight_2*array_2
# array([1., 2., 3., 4., 5.])

Прямое решение NumPy, использующее np.average, будет следующим, где axis=0 означает взять среднее значение по строке (используя оба столбца). np.vstack() просто складывает два массива по вертикали.

np.average(np.vstack((array_1, array_2)), axis=0, weights=[weight_1, weight_2])

Как указал @yatu, вы также можете передать список ваших массивов и указать ось

np.average([array_1, array_2], axis=0, weights=[weight_1, weight_2])

Сравнение времени, вдохновленное комментариями к ответу @ yatu : Как вы можете видеть, понимание списка и zip здесь немного быстрее, но тогда это представление для небольших массивов. Я уверен, что для больших массивов векторизованное решение займет

метод Девеша

%timeit result = [ item1 * weight_1 + item2 * weight_2 for item1, item2 in zip(array_1, array_2)]
# 25.5 µs ± 3.75 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

%timeit np.average([array_1, array_2], axis=0, weights=[weight_1, weight_2])
# 42.9 µs ± 2.94 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

%timeit np.average(np.vstack((array_1, array_2)), axis=0, weights=[weight_1, weight_2])
# 44.8 µs ± 4.98 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
2 голосов
/ 27 мая 2019

Учитывая, что вы используете NumPy , вы можете легко векторизовать это, выполнив:

array_1 = np.array([0,1,2,3,4])
array_2 = np.array([2,3,4,5,6])

weight_1 = 0.5
weight_2 = 0.5

array_1*weight_1 + array_2*weight_2
# array([1., 2., 3., 4., 5.])

Можно ли это обобщить для нескольких массивов и весов?

Для более обобщенного ответа лучше всего использовать np.average, который принимает array_like как для массивов, так и weights для применения ккаждый из них:

np.average([array_1, array_2], weights=[weight_1, weight_2], axis=0)
# array([1., 2., 3., 4., 5.])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...