1

I just ended up being confused about this for a while, so I thought I'd document in Q&A format - although more thorough explanations are more than welcome.

Let's say, I have a 2D numpy array, say xm below:

$ python3
Python 3.8.9 (default, Apr  3 2021, 09:30:04)  [GCC 10.2.0 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
import numpy as np
x = y = np.linspace(0,1.0, 4)
xm,ym = np.meshgrid(x,y)
xm
array([[0.        , 0.33333333, 0.66666667, 1.        ],
       [0.        , 0.33333333, 0.66666667, 1.        ],
       [0.        , 0.33333333, 0.66666667, 1.        ],
       [0.        , 0.33333333, 0.66666667, 1.        ]])
>>>

... and I want to replace each element, with an array of 3 elements - say, with: the basis [1.0, 1.0, 0.5], multiplied by the scalar value of each element of the 2D array.

Multiplication of a numpy array with a scalar is trivial:

xm*2
array([[0.        , 0.66666667, 1.33333333, 2.        ],
       [0.        , 0.66666667, 1.33333333, 2.        ],
       [0.        , 0.66666667, 1.33333333, 2.        ],
       [0.        , 0.66666667, 1.33333333, 2.        ]])

... but attempting to do "scalar (element od 2D array) times list" trivially does not work:

xm*np.array([1,1])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: operands could not be broadcast together with shapes (4,4) (2,)

... and trying to cheat by iterating through all the elements of the 2D array, and replacing each with a list/array, also fails:

for ir, irow in enumerate(xm):
  for ic, icol in enumerate(irow):
    xm[ir][ic] = icol*np.array([1, 1, 0.5])
...
TypeError: only size-1 arrays can be converted to Python scalars

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
ValueError: setting an array element with a sequence.

Yeah - but I do want do set an array element with a sequence - or at least, obtain the equivalent kind of array. How do I do that?

2 Answers 2

1

Use:

xm[:, :, np.newaxis]*np.array([[1.0, 1.0, 0.5]])

Output:

array([[[0.        , 0.        , 0.        ],
    [0.33333333, 0.33333333, 0.16666667],
    [0.66666667, 0.66666667, 0.33333333],
    [1.        , 1.        , 0.5       ]],

   [[0.        , 0.        , 0.        ],
    [0.33333333, 0.33333333, 0.16666667],
    [0.66666667, 0.66666667, 0.33333333],
    [1.        , 1.        , 0.5       ]],

   [[0.        , 0.        , 0.        ],
    [0.33333333, 0.33333333, 0.16666667],
    [0.66666667, 0.66666667, 0.33333333],
    [1.        , 1.        , 0.5       ]],

   [[0.        , 0.        , 0.        ],
    [0.33333333, 0.33333333, 0.16666667],
    [0.66666667, 0.66666667, 0.33333333],
    [1.        , 1.        , 0.5       ]]])
Sign up to request clarification or add additional context in comments.

Comments

1

Turns out, I "simply" have to reshape the arrays - basically:

  • first reshape xm of shape (4, 4) to 1D numpy array, which then has shape (16, 1);
  • multuplying each (scalar) element of that with the 1d numpy array basis, which has shape (3,), is trivial -- and we obtain a result with is an array of 3-element arrays, with a shape of (16, 3);
  • reshape that result into a numpy array of shape (4, 4, 3) - basically, we got a 3D array/matrix now
np.reshape( np.reshape(xm, (-1,1))*np.array([1,1,0.5]), (xm.shape[0], xm.shape[1], 3) )
array([[[0.        , 0.        , 0.        ],
        [0.33333333, 0.33333333, 0.16666667],
        [0.66666667, 0.66666667, 0.33333333],
        [1.        , 1.        , 0.5       ]],

       [[0.        , 0.        , 0.        ],
        [0.33333333, 0.33333333, 0.16666667],
        [0.66666667, 0.66666667, 0.33333333],
        [1.        , 1.        , 0.5       ]],

       [[0.        , 0.        , 0.        ],
        [0.33333333, 0.33333333, 0.16666667],
        [0.66666667, 0.66666667, 0.33333333],
        [1.        , 1.        , 0.5       ]],

       [[0.        , 0.        , 0.        ],
        [0.33333333, 0.33333333, 0.16666667],
        [0.66666667, 0.66666667, 0.33333333],
        [1.        , 1.        , 0.5       ]]])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.