问题
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