create a 20x20 matrix using numpy broadcast

廉价感情. 提交于 2021-02-11 14:24:19

问题


I'm looking how to create a matrix of 20x20 using Numpy broadcasting, result should look like:

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90, 96, 102, 108, 114, 120, 0, 7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98, 105, 112, 119, 126, 133, 140, 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128, 136, 144, 152, 160, 0, 9, 18, 27, 36, 45, 54, 63, 72, 81, 90, 99, 108, 117, 126, 135, 144, 153, 162, 171, 180, 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 0, 11, 22, 33, 44, 55, 66, 77, 88, 99, 110, 121, 132, 143, 154, 165, 176, 187, 198, 209, 220, 0, 12, 24, 36, 48, 60, 72, 84, 96, 108, 120, 132, 144, 156, 168, 180, 192, 204, 216, 228, 240, 0, 13, 26, 39, 52, 65, 78, 91, 104, 117, 130, 143, 156, 169, 182, 195, 208, 221, 234, 247, 260, 0, 14, 28, 42, 56, 70, 84, 98, 112, 126, 140, 154, 168, 182, 196, 210, 224, 238, 252, 266, 280, 0, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150, 165, 180, 195, 210, 225, 240, 255, 270, 285, 300, 0, 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256, 272, 288, 304, 320, 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255, 272, 289, 306, 323, 340, 0, 18, 36, 54, 72, 90, 108, 126, 144, 162, 180, 198, 216, 234, 252, 270, 288, 306, 324, 342, 360, 0, 19, 38, 57, 76, 95, 114, 133, 152, 171, 190, 209, 228, 247, 266, 285, 304, 323, 342, 361, 380, 0, 20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 260, 280, 300, 320, 340, 360, 380, 400]

I tried the following:

 broadcast = np.arange(0, 21) *(20)
 print(broadcast)

Got:

[0 20 40 60 80 100 120 140 160 180 200 220 240 260 280 300 320 340 360 380 400]

When providing a broadcast of a range to multiply by, such as: (0, 21) * (0, 21) it results in the below error:

ValueError: operands could not be broadcast together with shapes (21,) (2,)

Is it possible to broadcast by a range ?


回答1:


Let's take your calculations step by step:

First make an array with arange:

In [166]: x = np.arange(5)                                                                           
In [167]: x                                                                                          
Out[167]: array([0, 1, 2, 3, 4])

We can multiply it by a scalar:

In [168]: x * (5)                                                                                    
Out[168]: array([ 0,  5, 10, 15, 20])

The () add nothing here.

Then you try to multiply by a tuple:

In [169]: x * (0, 5)                                                                                 
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-169-b6f23a3901bc> in <module>
----> 1 x * (0, 5)

ValueError: operands could not be broadcast together with shapes (5,) (2,) 

I suspect you expected to somehow multiply the (0,5) 'range' by (0,5) 'range'. That's not how it works. (0,5) is a tuple. In the multiplication expression, the array x controls the action, so the tuple is turned into an array, np.array([0,2]). By broadcasting rules, a 5 element array can't multiply with a 2 element one.

Your first print suggests you want to multiply two arrays (n,) shape array to produces a (n,n) array, or (n*n,).

We could reshape x to (5,1):

In [170]: x[:,None]                                                                                  
Out[170]:           # elsewhere this might called a column vector
array([[0],
       [1],
       [2],
       [3],
       [4]])

Now by broadcasting:

In [171]: x*x[:,None]                                                                                
Out[171]: 
array([[ 0,  0,  0,  0,  0],
       [ 0,  1,  2,  3,  4],
       [ 0,  2,  4,  6,  8],
       [ 0,  3,  6,  9, 12],
       [ 0,  4,  8, 12, 16]])

and if you want it as 1d:

In [172]: np.ravel(x*x[:,None])                                                                      
Out[172]: 
array([ 0,  0,  0,  0,  0,  0,  1,  2,  3,  4,  0,  2,  4,  6,  8,  0,  3,
        6,  9, 12,  0,  4,  8, 12, 16])

The [171] action is: (5,) * (5,1) => (1,5) * (5,1) => (5,5)

The basic broadcasting rules are:

  • leading dimensions might be added to match
  • size 1 dimensions might be adjusted to match

This multiplication is like the outer or cartesian product of two arrays:

In [173]: np.outer(x,x)                                                                              
Out[173]: 
array([[ 0,  0,  0,  0,  0],
       [ 0,  1,  2,  3,  4],
       [ 0,  2,  4,  6,  8],
       [ 0,  3,  6,  9, 12],
       [ 0,  4,  8, 12, 16]])



回答2:


I believe you are looking for something like this:

a = np.arange(21)
b = np.arange(21)
a[:, np.newaxis] * b

More can be found here: https://numpy.org/doc/stable/user/basics.broadcasting.html



来源:https://stackoverflow.com/questions/63125652/create-a-20x20-matrix-using-numpy-broadcast

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!