arr1 = np.array(
[[[ 820, 820, 720, 720],
[ 860, 860, 500, 500],
[ 860, 860, 500, 500],
[ 860, 860, 500, 500]],
[[5980, 5980, 4760, 4760],
[7500, 7500, 7940, 7940],
[7500, 7500, 7940, 7940],
[7500, 7500, 7940, 7940]],
[[ 740, 740, 440, 440],
[1240, 1240, 1140, 1140],
[1240, 1240, 1140, 1140],
[1240, 1240, 1140, 1140]],
[[3200, 3200, 7600, 7600],
[ 900, 900, 400, 400],
[ 900, 900, 400, 400],
[ 900, 900, 400, 400]]]
)
arr2 = np.array(
[[ 1, 2, 1, 1],
[ 1, 0, 3, 3],
[ 3, 0, 2, 2],
[ 3, 0, 1, 2]]
)
то, что мы пытаемся сделать, это разрезать временную ось arr1
, используя индексы, хранящиеся в arr2
, теперь python позволяет разрезать только с использованием :
, которое мы можем только передать при буквальном индексировании ie не использует другой массив для индексации. поэтому нам нужен обходной способ сделать это
, одним из способов может быть изменение всех значений в arr1
, которые были бы проигнорированы при нарезке, на 0
сейчас чтобы найти индексы значений, которые нужно игнорировать, мы делаем это
no_days = arr1.shape[0]
arr3 = np.arange(no_days)
arr3.shape = [-1,1,1]
arr3
>>> [[[0]],
[[1]],
[[2]],
[[3]]]
filter = arr3 < arr2
filter.shape
>>> (4, 4, 4)
arr3
- это массив индексов временной оси. мы сравнили его с arr2
, и теперь у нас есть булевы индексы значений, которые нужно игнорировать в filter
, и мы можем установить их на 0
arr1[filter] = 0
arr1
>>> [[[ 0, 0, 0, 0],
[ 0, 860, 0, 0],
[ 0, 860, 0, 0],
[ 0, 860, 0, 0]],
[[5980, 0, 4760, 4760],
[7500, 7500, 0, 0],
[ 0, 7500, 0, 0],
[ 0, 7500, 7940, 0]],
[[ 740, 740, 440, 440],
[1240, 1240, 0, 0],
[ 0, 1240, 1140, 1140],
[ 0, 1240, 1140, 1140]],
[[3200, 3200, 7600, 7600],
[ 900, 900, 400, 400],
[ 900, 900, 400, 400],
[ 900, 900, 400, 400]]]
, у нас может возникнуть соблазн использовать arr1.mean(axis= 0)
, но при этом также учитываются все допустимые записи 0
, которые влияют на среднее значение, вместо того, чтобы игнорировать их
, поэтому вместо этого мы суммируем arr1
по оси времени и не делим его ни на какие элементы, которые были бы в срезах
arr1.sum(axis= 0) / (no_days - arr2)
>>> [[3306.66666667, 1970. , 4266.66666667, 4266.66666667],
[3213.33333333, 2625. , 400. , 400. ],
[ 900. , 2625. , 770. , 770. ],
[ 900. , 2625. , 3160. , 770. ]]
если t < x*y
, то следующее будет работать быстрее
arr1.sum(axis= 0) / (~filter).astype(int).sum(axis= 0)