【问题标题】:Iterate over an array and apply it to a function遍历数组并将其应用于函数
【发布时间】:2020-05-23 17:57:10
【问题描述】:

在 python 中,我使用函数“q”迭代 P 中的每一列和 4,4 数组。 喜欢:

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 进行迭代还是有其他方法?

【问题讨论】:

  • np.dot(0, 2, q_u) - 这应该做什么?

标签: python arrays function numpy multidimensional-array


【解决方案1】:

将令人费解的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 个二维数组,每个数组每列有一行 P

我在 [38] 中计时的列表解析产生 4 个大小 (3,) 的数组,即 P 的每列一个数组。 apply_along_axis 掩盖了这一点,将它们连接到最后一个维度(就像我的 stack with 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 输出“完整”,从而更容易传递给另一个函数。

【讨论】:

    【解决方案2】:

    使用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 让zip 仅根据arr.T 的长度修剪元组

    【讨论】:

      猜你喜欢
      • 2021-12-26
      • 1970-01-01
      • 2021-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-02
      • 1970-01-01
      相关资源
      最近更新 更多