遍历数组并将其应用于函数



在python中,我迭代P中的每一列,即4,4数组,函数"q"。 喜欢:

P = np.array([[1, 0, 0, 1], [0, 1, 0, 0], [0, 0, 0.5, 0], [0, 0, 0.5, 0]])

def q(q_u):
q = np.array(
[
[np.dot(0, 2, q_u)],
[np.zeros((4, 1), dtype=int)],
[np.zeros((2, 1), dtype=int)],
],
dtype=object,
)
return q

np.apply_along_axis(q, axis=0, arr=P)

我得到一个 (3,1,4( 数组,将 q 函数应用于 P 数组。这是正确的。但是如何保存并稍后将 4 (3,1( 数组调用到字典中,以便稍后将其应用于另一个需要 (3,1( 数组的函数 printR。

printR(60, res, q)

应该将 4 个数组添加到字典中以便使用 PrintR 进行迭代还是有另一种方法?

使用transposezip创建字典。

要创建 4 个(1,3),只需将它们传递给 dict

arr = np.apply_along_axis(q, axis=0, arr=P)
d = dict(zip(range(arr.size), arr.T))
Out[259]:
{0: array([[0, array([[0],
[0],
[0],
[0]]),
array([[0],
[0]])]], dtype=object), 1: array([[0, array([[0],
[0],
[0],
[0]]),
array([[0],
[0]])]], dtype=object), 2: array([[0, array([[0],
[0],
[0],
[0]]),
array([[0],
[0]])]], dtype=object), 3: array([[0, array([[0],
[0],
[0],
[0]]),
array([[0],
[0]])]], dtype=object)}
In [260]: d[0].shape
Out[260]: (1, 3)

要创建 4 的(3,1),请使用字典理解

d = {k: v.T for k, v in zip(range(arr.size), arr.T)}
Out[269]:
{0: array([[0],
[array([[0],
[0],
[0],
[0]])],
[array([[0],
[0]])]], dtype=object), 1: array([[0],
[array([[0],
[0],
[0],
[0]])],
[array([[0],
[0]])]], dtype=object), 2: array([[0],
[array([[0],
[0],
[0],
[0]])],
[array([[0],
[0]])]], dtype=object), 3: array([[0],
[array([[0],
[0],
[0],
[0]])],
[array([[0],
[0]])]], dtype=object)}
In [270]: d[0].shape
Out[270]: (3, 1)

注意:我故意使用arr.size让拉链修剪元组仅基于arr.T的长度

将令人费解的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*P0.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掩盖了这一点,将它们连接到最后一个维度上(就像我使用 axis=2 的stack一样(。

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输出"完整",使其更容易传递给另一个函数。

最新更新