Исправление загадки dot
в
[np.dot(0.2, q_u)],
приводит к ost
в вашем другом вопросе.
Я все еще удивляюсь, почему вы настаиваете на использовании apply_along_axis
. Это не имеет никаких преимуществ в скорости. Сравните эти временные значения:
In [36]: timeit np.apply_along_axis(q, axis=0, arr=P)
141 µs ± 112 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [37]: timeit np.stack([q(P[:,i]) for i in range(P.shape[1])], axis=2)
72.1 µs ± 500 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [38]: timeit [q(P[:,i]) for i in range(P.shape[1])]
53 µs ± 42.2 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
Эта строка dot(0.2, q_u)
просто делает 0.2*q_u
, что для P
может быть 0.2*P
или 0.2*P.T
.
Давайте изменим q
чтобы опустить размеры 1, чтобы сделать более компактный дисплей:
In [49]: def q1(q_u):
...: q = np.array(
...: [
...: np.dot(0.2, q_u),
...: np.zeros((4,), dtype=int),
...: np.zeros((2,), dtype=int),
...: ],
...: dtype=object,
...: )
...: return q
...:
In [50]: np.apply_along_axis(q1, axis=0, arr=P)
Out[50]:
array([[array([0.2, 0. , 0. , 0. ]), array([0. , 0.2, 0. , 0. ]),
array([0. , 0. , 0.1, 0.1]), array([0.2, 0. , 0. , 0. ])],
[array([0, 0, 0, 0]), array([0, 0, 0, 0]), array([0, 0, 0, 0]),
array([0, 0, 0, 0])],
[array([0, 0]), array([0, 0]), array([0, 0]), array([0, 0])]],
dtype=object)
In [51]: _.shape
Out[51]: (3, 4)
Мы можем генерировать одинаковые числа, расположенные немного по-разному с помощью:
In [52]: [0.2 * P.T, np.zeros((4,4),int), np.zeros((4,2),int)]
Out[52]:
[array([[0.2, 0. , 0. , 0. ],
[0. , 0.2, 0. , 0. ],
[0. , 0. , 0.1, 0.1],
[0.2, 0. , 0. , 0. ]]),
array([[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]]),
array([[0, 0],
[0, 0],
[0, 0],
[0, 0]])]
Вы делаете 3 2d массивы, каждый с одной строкой на столбец P
.
Понимание списка, которое я рассчитал в [38], дает 4 массива размера (3,), то есть один массив на столбец P
. apply_along_axis
затемняет это, соединяя их в последнем измерении (как это делает мой stack
с axis = 2).
In [53]: [q1(P[:,i]) for i in range(P.shape[1])]
Out[53]:
[array([array([0.2, 0. , 0. , 0. ]), array([0, 0, 0, 0]), array([0, 0])],
dtype=object),
array([array([0. , 0.2, 0. , 0. ]), array([0, 0, 0, 0]), array([0, 0])],
dtype=object),
array([array([0. , 0. , 0.1, 0.1]), array([0, 0, 0, 0]), array([0, 0])],
dtype=object),
array([array([0.2, 0. , 0. , 0. ]), array([0, 0, 0, 0]), array([0, 0])],
dtype=object)]
Понимание списка не только быстрое, но оно также сохраняет q
выведите «intact», что облегчает переход к другой функции.