我怎样才能用 numpy 优雅地产生这种稀疏模式?
How can I produce this sparsity pattern elegantly with numpy?
对于 D 维问题,我正在尝试生成具有特定稀疏模式的 2d ndarray
。
我一直在尝试弄清楚如何使用 np.meshgrid
之类的方法交错向量,但就是做不到。
稀疏矩阵(实际上不需要稀疏,只包含 0
s 和 1
s)的形状为 (2^D, D)
,其中 D 是维数.
对于 D=2,矩阵如下所示:
two_d = [
[0, 0],
[1, 0],
[0, 1],
[1, 1],
]
对于 D=3 是这样的:
three_d = [
[0, 0, 0],
[1, 0, 0],
[0, 1, 0],
[1, 1, 0],
[0, 0, 1],
[1, 0, 1],
[0, 1, 1],
[1, 1, 1],
]
这是一个非常明显的稀疏模式,但我正在努力弄清楚如何用 numpy 优雅地重现它。
注意:行顺序实际上并不重要,只要所有行都存在即可。
仁者见仁,智者见智。有许多工具可以生成这些值;将它们放入所需的布局只是基本的 numpy
操作。
生成这些数组的一个很好的基本方法是:
In [6]: np.array(list(itertools.product([0,1],repeat=2)))
Out[6]:
array([[0, 0],
[0, 1],
[1, 0],
[1, 1]])
In [7]: np.array(list(itertools.product([0,1],repeat=3)))
Out[7]:
array([[0, 0, 0],
[0, 0, 1],
[0, 1, 0],
[0, 1, 1],
[1, 0, 0],
[1, 0, 1],
[1, 1, 0],
[1, 1, 1]])
来自评论:
In [16]: np.indices((2,2))
Out[16]:
array([[[0, 0],
[1, 1]],
[[0, 1],
[0, 1]]])
In [17]: np.indices((2,)*2).T.reshape(-1,2)
Out[17]:
array([[0, 0],
[1, 0],
[0, 1],
[1, 1]])
In [18]: np.indices((2,)*3).T.reshape(-1,3)
Out[18]:
array([[0, 0, 0],
[1, 0, 0],
...
In [20]: np.meshgrid(np.arange(2),np.arange(2),indexing='ij')
Out[20]:
[array([[0, 0],
[1, 1]]),
array([[0, 1],
[0, 1]])]
In [21]: np.transpose(np.meshgrid(np.arange(2),np.arange(2),indexing='ij')).resh
...: ape(-1,2)
Out[21]:
array([[0, 0],
[1, 0],
[0, 1],
[1, 1]])
'ij' 不是必需的;它只是生成一组初始数组,看起来像 indices
.
mgrid
也可以用。和:
np.array(list(np.ndindex(2,2,2)))
另一种方法是逆向工程three_d
。
In [55]: res = np.zeros((2**3,3),int)
设置第一列的所有其他元素很简单:
In [56]: res[1::2,0]=1
In [57]: res
Out[57]:
array([[0, 0, 0],
[1, 0, 0],
[0, 0, 0],
[1, 0, 0],
[0, 0, 0],
[1, 0, 0],
[0, 0, 0],
[1, 0, 0]])
在第二个中设置值对比较棘手:
In [58]: res[:,1].reshape(-1,4)[:,2:]=1
In [59]: res
Out[59]:
array([[0, 0, 0],
[1, 0, 0],
[0, 1, 0],
[1, 1, 0],
[0, 0, 0],
[1, 0, 0],
[0, 1, 0],
[1, 1, 0]])
设置第三个连续块同样简单:
In [60]: res[4:,2]=1
In [61]: res
Out[61]:
array([[0, 0, 0],
[1, 0, 0],
[0, 1, 0],
[1, 1, 0],
[0, 0, 1],
[1, 0, 1],
[0, 1, 1],
[1, 1, 1]])
对于 D 维问题,我正在尝试生成具有特定稀疏模式的 2d ndarray
。
我一直在尝试弄清楚如何使用 np.meshgrid
之类的方法交错向量,但就是做不到。
稀疏矩阵(实际上不需要稀疏,只包含 0
s 和 1
s)的形状为 (2^D, D)
,其中 D 是维数.
对于 D=2,矩阵如下所示:
two_d = [
[0, 0],
[1, 0],
[0, 1],
[1, 1],
]
对于 D=3 是这样的:
three_d = [
[0, 0, 0],
[1, 0, 0],
[0, 1, 0],
[1, 1, 0],
[0, 0, 1],
[1, 0, 1],
[0, 1, 1],
[1, 1, 1],
]
这是一个非常明显的稀疏模式,但我正在努力弄清楚如何用 numpy 优雅地重现它。
注意:行顺序实际上并不重要,只要所有行都存在即可。
仁者见仁,智者见智。有许多工具可以生成这些值;将它们放入所需的布局只是基本的 numpy
操作。
生成这些数组的一个很好的基本方法是:
In [6]: np.array(list(itertools.product([0,1],repeat=2)))
Out[6]:
array([[0, 0],
[0, 1],
[1, 0],
[1, 1]])
In [7]: np.array(list(itertools.product([0,1],repeat=3)))
Out[7]:
array([[0, 0, 0],
[0, 0, 1],
[0, 1, 0],
[0, 1, 1],
[1, 0, 0],
[1, 0, 1],
[1, 1, 0],
[1, 1, 1]])
来自评论:
In [16]: np.indices((2,2))
Out[16]:
array([[[0, 0],
[1, 1]],
[[0, 1],
[0, 1]]])
In [17]: np.indices((2,)*2).T.reshape(-1,2)
Out[17]:
array([[0, 0],
[1, 0],
[0, 1],
[1, 1]])
In [18]: np.indices((2,)*3).T.reshape(-1,3)
Out[18]:
array([[0, 0, 0],
[1, 0, 0],
...
In [20]: np.meshgrid(np.arange(2),np.arange(2),indexing='ij')
Out[20]:
[array([[0, 0],
[1, 1]]),
array([[0, 1],
[0, 1]])]
In [21]: np.transpose(np.meshgrid(np.arange(2),np.arange(2),indexing='ij')).resh
...: ape(-1,2)
Out[21]:
array([[0, 0],
[1, 0],
[0, 1],
[1, 1]])
'ij' 不是必需的;它只是生成一组初始数组,看起来像 indices
.
mgrid
也可以用。和:
np.array(list(np.ndindex(2,2,2)))
另一种方法是逆向工程three_d
。
In [55]: res = np.zeros((2**3,3),int)
设置第一列的所有其他元素很简单:
In [56]: res[1::2,0]=1
In [57]: res
Out[57]:
array([[0, 0, 0],
[1, 0, 0],
[0, 0, 0],
[1, 0, 0],
[0, 0, 0],
[1, 0, 0],
[0, 0, 0],
[1, 0, 0]])
在第二个中设置值对比较棘手:
In [58]: res[:,1].reshape(-1,4)[:,2:]=1
In [59]: res
Out[59]:
array([[0, 0, 0],
[1, 0, 0],
[0, 1, 0],
[1, 1, 0],
[0, 0, 0],
[1, 0, 0],
[0, 1, 0],
[1, 1, 0]])
设置第三个连续块同样简单:
In [60]: res[4:,2]=1
In [61]: res
Out[61]:
array([[0, 0, 0],
[1, 0, 0],
[0, 1, 0],
[1, 1, 0],
[0, 0, 1],
[1, 0, 1],
[0, 1, 1],
[1, 1, 1]])