实例化一个带有x零和其余矩阵的矩阵

Pas*_*ten 4 python arrays for-loop numpy

我希望能够快速实例化一个矩阵,其中一行中的前几个(可变数量)单元格为0,其余为1.

想象一下,我们想要一个3x4矩阵.

我首先将矩阵实例化为所有矩阵:

ones = np.ones([4,3])
Run Code Online (Sandbox Code Playgroud)

然后想象我们有一个数组,宣告有多少前导零:

arr = np.array([2,1,3,0]) # first row has 2 zeroes, second row 1 zero, etc
Run Code Online (Sandbox Code Playgroud)

要求的结果:

array([[0, 0, 1],
       [0, 1, 1],
       [0, 0, 0],
       [1, 1, 1]])
Run Code Online (Sandbox Code Playgroud)

显然,这也可以以相反的方式完成,但我会考虑1是默认值的方法,并且将替换零.

什么是避免一些愚蠢循环的最佳方法?

War*_*ser 6

这是一种方式. n是结果中的列数.行数由len(arr).确定.

In [29]: n = 5

In [30]: arr = np.array([1, 2, 3, 0, 3])

In [31]: (np.arange(n) >= arr[:, np.newaxis]).astype(int)
Out[31]: 
array([[0, 1, 1, 1, 1],
       [0, 0, 1, 1, 1],
       [0, 0, 0, 1, 1],
       [1, 1, 1, 1, 1],
       [0, 0, 0, 1, 1]])
Run Code Online (Sandbox Code Playgroud)

解释这是如何工作有两个部分.首先,如何用m零和一行创建一行n-m?为此,我们np.arange用来创建一个值为[0,1,...,n-1]的行:

In [35]: n
Out[35]: 5

In [36]: np.arange(n)
Out[36]: array([0, 1, 2, 3, 4])
Run Code Online (Sandbox Code Playgroud)

接下来,将该数组与m:

In [37]: m = 2

In [38]: np.arange(n) >= m
Out[38]: array([False, False,  True,  True,  True], dtype=bool)
Run Code Online (Sandbox Code Playgroud)

这给出了一个布尔值数组; 第一个m值为False,其余值为True.通过将这些值转换为整数,我们得到一个0和1的数组:

In [39]: (np.arange(n) >= m).astype(int)
Out[39]: array([0, 0, 1, 1, 1])
Run Code Online (Sandbox Code Playgroud)

要通过一个执行此数组m值(你的arr),我们用广播 ; 这是解释的第二个关键思想.

请注意arr[:, np.newaxis]:

In [40]: arr
Out[40]: array([1, 2, 3, 0, 3])

In [41]: arr[:, np.newaxis]
Out[41]: 
array([[1],
       [2],
       [3],
       [0],
       [3]])
Run Code Online (Sandbox Code Playgroud)

也就是说,arr[:, np.newaxis]重塑arr为具有形状(5,1)的2-d阵列.(arr.reshape(-1, 1)原本可以使用它.)现在,当我们将其与np.arange(n)(带有长度的1-d数组n)进行比较时,广播开始了:

In [42]: np.arange(n) >= arr[:, np.newaxis]
Out[42]: 
array([[False,  True,  True,  True,  True],
       [False, False,  True,  True,  True],
       [False, False, False,  True,  True],
       [ True,  True,  True,  True,  True],
       [False, False, False,  True,  True]], dtype=bool)
Run Code Online (Sandbox Code Playgroud)

正如@RogerFan在他的评论中指出的那样,这基本上是使用该>=操作的参数的外积.

最终的类型转换int会给出所需的结果:

In [43]: (np.arange(n) >= arr[:, np.newaxis]).astype(int)
Out[43]: 
array([[0, 1, 1, 1, 1],
       [0, 0, 1, 1, 1],
       [0, 0, 0, 1, 1],
       [1, 1, 1, 1, 1],
       [0, 0, 0, 1, 1]])
Run Code Online (Sandbox Code Playgroud)