pythonnumpymatrixvectordeprecation-warning

Creating Matrix from Vector Entries and Deprecation Warning from NumPy


I want to create a square matrix, let say 4X4, which the entries are taken from a vector, with length 16. This vector entry will be arranged in the column of matrix. Suppose that u is a vector with length 16, and M is a matrix with size 4x4. Then, M(1,1)=u(1), M(2,1)=u(2), M(3,1)=u(3), M(4,1)=u(4), M(1,2)=u(5), M(2,2)=u(6), M(3,2)=u(7), and soon.

This is the code that I wrote:

import numpy as np

Nx = Ny = 4
u0 = np.zeros([Nx*Ny, 1])
U0 = np.zeros([Nx, Ny])

aa = 0
for j in range(Ny):
  for i in range(Nx):
    U0[i][j] = u0[i+aa]
    if (i%Nx) == 3:
      aa = aa+4
    else:
      aa = aa

where Nx=Ny=4, and u0 is a vector with length 16.

After I run the code, this is the result:

:79: DeprecationWarning: Conversion of an array with ndim > 0 to a scalar is deprecated, and will error in future. Ensure you extract a single element from your array before performing this operation. (Deprecated NumPy 1.25.) U0[i][j]=u0[i+aa]

Can someone please help me interpret this result? And what is wrong with my code?


Solution

  • Although the required operation can be done by reshaping like u.rehape((4,4), order='F'), the initial approach can be reasonable in some situations of copying data. So let's make it work.

    The issue you experienced stems from the fact, that you're working technically not with a vector but with a 2-dimentional array. So the expression like u0[i+aa] returns not a scalar but a vector with a single item. It still can be used as a scalar in assignment, and what you see is not an error but just a deprecation warning. To get rid of this warning and ensure that the code will work with future versions of Numpy, you need to add an additional index to get the scalar, like u0[i+aa, 0].

    I'd make additional fixes you may be interested in:

    import numpy as np
    
    Nx = Ny = 4
    vector = np.arange(Nx*Ny).reshape(-1, 1)          # get a vertical vector
    matrix = np.zeros([Nx, Ny], dtype=vector.dtype)   # keep dtype of the vector as long as possible
    
    start = 0
    for column in range(Ny):
        matrix[:, column] = vector[start:start+Nx, 0]
        start += Nx
    
    print('vector:', vector, '\nmatrix:', matrix, sep='\n')
    
    vector:
    [[ 0]
     [ 1]
     [ 2]
     [ 3]
     [ 4]
     [ 5]
     [ 6]
     [ 7]
     [ 8]
     [ 9]
     [10]
     [11]
     [12]
     [13]
     [14]
     [15]]
    
    matrix:
    [[ 0  4  8 12]
     [ 1  5  9 13]
     [ 2  6 10 14]
     [ 3  7 11 15]]