将 a[i+j] 数组映射到 A[i,j] 矩阵

Tho*_*s W 5 python arrays numpy matrix

我有一个数组,并想为其a创建一个新矩阵。例子:AA[i,j] = a[i+j]

import numpy as np

a = np.random.rand(3)
A = np.zeros((2,2));

for i in range(2):
    for j in range(2):
        A[i,j] = a[i+j]
Run Code Online (Sandbox Code Playgroud)

有没有一种方法可以在不使用 for 循环的情况下做到这一点?(与numpy)

Iva*_*van 3

使用stride_tricks.as_strided

这将是一个完美的用例stride_tricks

from np.lib.stride_tricks import as_strided
Run Code Online (Sandbox Code Playgroud)

将步幅设置为(8, 8) (1, 1)按照槽数)。这样我们基本上将结果数组映射Ai, j -> k = i + j. 更详细的描述是:我们将每对映射到一个由步幅定义的i, j自然数,其中和是步幅设置为s,。这样就得到了想要的结果:。kk = i*s_i + j*s_js_is_j1 k = i + jA[i, j] = a[k] = a[i + j]

>>> a
array([0.53954179, 0.51789927, 0.33982179])

>>> A = as_strided(a, shape=(2,2), strides=(8,8))
array([[0.53954179, 0.51789927],
       [0.51789927, 0.33982179]])
Run Code Online (Sandbox Code Playgroud)
其他注意事项

a更通用的解决方案是从的元数据中获取形状和步幅。

  • 的形状A由 给出(len(a)//2+1,)*2

  • 正如@Daniel F所指出的,内存插槽大小并不总是等于8,这确实取决于数组的数据类型。最好定义stridesfroma的步幅:a.strides*2

这归结为:

>>> A = as_strided(a, shape=(len(a)//2+1,)*2, strides=a.strides*2)
Run Code Online (Sandbox Code Playgroud)

使用网格索引

或者,您可以构造一个坐标网格(可以使用 来实现itertools.product),然后将适当的值从 复制aA

i, j = np.array(list(product(range(2), range(2)))).T
Run Code Online (Sandbox Code Playgroud)

然后初始化Acopy

>>> A = np.zeros((2,2))
>>> A[i, j] = a[i + j]
Run Code Online (Sandbox Code Playgroud)

然而,与该方法相比,这将使内存使用量增加一倍as_strided