Здесь векторизованный подход, использующий numpy вещание :
import numpy as np
t = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
P = np.array([30, 69, 56, 70, 90, 59, 87, 10, 20], dtype=float)
i = np.arange(1, 8 , 1)
t_inc= 2 + i
T = np.tile(t[:,None], len(i))
P = np.tile(P[:,None], len(i))
np.tile создает массив, повторяя его количество заданных раз, в в этом случае у нас будет len(i)
копий t
и P
, а именно:
P
array([[30., 30., 30., 30., 30., 30., 30.],
[69., 69., 69., 69., 69., 69., 69.],
[56., 56., 56., 56., 56., 56., 56.],
[70., 70., 70., 70., 70., 70., 70.],
[90., 90., 90., 90., 90., 90., 90.],
[59., 59., 59., 59., 59., 59., 59.],
[87., 87., 87., 87., 87., 87., 87.],
[10., 10., 10., 10., 10., 10., 10.],
[20., 20., 20., 20., 20., 20., 20.]])
Теперь мы обнуляем все элементы, не удовлетворяющие требуемому условию, используя np.logical_or :
P[np.logical_or(2>T, T>t_inc)]=0
P
array([[ 0., 0., 0., 0., 0., 0., 0.],
[69., 69., 69., 69., 69., 69., 69.],
[56., 56., 56., 56., 56., 56., 56.],
[ 0., 70., 70., 70., 70., 70., 70.],
[ 0., 0., 90., 90., 90., 90., 90.],
[ 0., 0., 0., 59., 59., 59., 59.],
[ 0., 0., 0., 0., 87., 87., 87.],
[ 0., 0., 0., 0., 0., 10., 10.],
[ 0., 0., 0., 0., 0., 0., 20.]])
Таким образом, мы храним в каждом столбце только элементы для усреднения, однако использование np.mean
приведет к неверному результату, поскольку знаменатель будет P.shape[0]
, т.е. нулевые элементы. В качестве обходного пути мы можем суммировать вдоль оси и разделить на общее количество ненулевых элементов, используя np.count_nonzero
:
np.sum(P, axis=0)/np.count_nonzero(P, axis=0)
array([62.5, 65., 71.25, 68.8, 71.83333333, 63., 57.625])