【问题标题】:rewriting loops functions in numpy without using for or while在不使用 for 或 while 的情况下重写 numpy 中的循环函数
【发布时间】:2021-11-13 19:25:34
【问题描述】:

我正在尝试使用 numpy 库重现以下函数,我想在不使用关键字 for 或 while 的情况下生成等效定义。我猜你需要使用广播、newaxis 和从 numpy 重塑。但是我是 numpy 的新手,并且不使用“for”或“while”来执行循环对我来说是一个令人费解的问题,尤其是在尝试使用嵌套循环时。

def _bcast(x):
            x1, x2 = x
            y = np.empty(x1.shape)
            for i in range(x1.shape[0]):
                for j in range(x1.shape[1]):
                    for k in range(x1.shape[2]):
                        y[i,j,k] = (x1[i,j,k]+4)*(4*x2[j,k] - 4)
            return y

def _bcast_ax(x):
            x1, x2 = x
            y = np.empty((x1.shape[0], x2.shape[0], x2.shape[1]))
            for i in range(x1.shape[0]):
                for j in range(x2.shape[0]):
                    for k in range(x2.shape[1]):
                        y[i,j,k] = (4+x1[i,k])*(4*x2[j,k]-4)
            return y

def bcast(x):
  
    return (x1+4) * (4*x2 -4) 

def bcast_ax(x):
   
    return (x**2)*(x[1]*2)*(x[2]**4) 

我尝试对这两个功能执行以下操作,但它们不起作用。

澄清一下,我需要这个测试通过 _bcast 和 bcast 产生相同的结果。 _bcast_ax 和 bcast_ax 相同

def test_bcast(self):
        def _bcast(x):
            x1, x2 = x
            y = np.empty(x1.shape)
            for i in range(x1.shape[0]):
                for j in range(x1.shape[1]):
                    for k in range(x1.shape[2]):
                        y[i,j,k] = (x1[i,j,k]+4)*(4*x2[j,k] - 4)
            return y

        X = [(np.random.randn(3,4,5), np.random.randn(4,5)) for _ in range(3)]
        self._test_fun(ac.bcast, _bcast, X)

【问题讨论】:

  • 您需要一个minimal reproducible example,并显示“不起作用”的功能的回溯。根据我的推理,第一个 _bast 不应该工作,因为索引不匹配。
  • X 是 3 个数组元组的列表。您的任何功能都不适用于此功能。给出正确的minimal reproducible example 并带有正确的缩进。

标签: python numpy loops


【解决方案1】:

专注于

y[i,j,k] = (x1[i,j,k]+4)*(4*x2[j,k] - 4)

这意味着yx1 具有相同的形状。 x2 具有相同的最后 2 个维度。我们可以重塑x2 拥有一个新的领先维度x2[None,...]

y = (x1+4)*(4*x2[None,...] - 4)

但是根据广播新的领先维度的规则是自动的

y = (x1+4)*(4*x2-4)

应该可以。

关键是了解broadcasting

测试

In [169]: x1, x2 = np.arange(24).reshape(2,3,4), np.arange(12).reshape(3,4)
In [170]:             y = np.empty(x1.shape)
     ...:             for i in range(x1.shape[0]):
     ...:                 for j in range(x1.shape[1]):
     ...:                     for k in range(x1.shape[2]):
     ...:                         y[i,j,k] = (x1[i,j,k]+4)*(4*x2[j,k] - 4)
     ...: 
In [171]: y
Out[171]: 
array([[[ -16.,    0.,   24.,   56.],
        [  96.,  144.,  200.,  264.],
        [ 336.,  416.,  504.,  600.]],

       [[ -64.,    0.,   72.,  152.],
        [ 240.,  336.,  440.,  552.],
        [ 672.,  800.,  936., 1080.]]])
In [172]: (x1+4)*(4*x2-4)
Out[172]: 
array([[[ -16,    0,   24,   56],
        [  96,  144,  200,  264],
        [ 336,  416,  504,  600]],

       [[ -64,    0,   72,  152],
        [ 240,  336,  440,  552],
        [ 672,  800,  936, 1080]]])

【讨论】:

  • 我不确定我是否遵循,应该 (x1+4)*(4*x2[None,...] - 4) 给我答案吗?我收到以下错误返回 (x1+4)*(4*x2[None,...] - 4) TypeError: can only concatenate tuple (not "int") to tuple
  • 我删除了“哎呀”块。 x1,x2=x 正在解包一个元组,所以原来的分析仍然有效。
猜你喜欢
  • 1970-01-01
  • 2020-03-19
  • 2012-11-21
  • 1970-01-01
  • 1970-01-01
  • 2018-10-15
  • 2019-10-10
  • 2017-03-25
  • 2022-11-05
相关资源
最近更新 更多