pythonnumpytime-seriesdata-analysissvd

how to run SVD in python with a 1xn matrix?


So i want to run an algorithm on my dataset, and the first step is the Singular Value Decomposition (SVD). I am basing it on an example i found on a book, and there they use MatLab and run SVD on this time series that has dimension 1xn. However, when I try to run it in python using the numpy.linalg.svd, this error always comes that the matrix needs to have at least 2xn dimension.

So my question is: how can I run SVD with an 1xn matrix (or a vector) without getting this error? Does anyone have an idea? It'd be very much apreciated :)

Now i know i could time stack this data matrix, but I first wanted to run it without doing this step to see what kind of eigenvalues I would get (and I know they would not accurately describe my data, but I still want to see exactly how).


Solution

  • In MATLAB everything is 2d (or more). In numpy, arrays may be 1d. Keep that in mind when apply MATLAB examples to numpy.

    this error always comes that the matrix needs to have at least 2xn dimension.

    What exactly do you mean by 2xn dimension? To most numpy users that means a shape of (2,n), as opposed to (1,n) or (n,).

    When asking SO questions it's best to include actual code,and to quote the error exactly.

    When I use svd on a 3 element list, which becomes a (3,) array:

    In [27]: np.linalg.svd([1,2,3])
    ---------------------------------------------------------------------------
    LinAlgError                               Traceback (most recent call last)
    Cell In[27], line 1
    ----> 1 np.linalg.svd([1,2,3])
    
    File <__array_function__ internals>:200, in svd(*args, **kwargs)
    
    File ~\miniconda3\lib\site-packages\numpy\linalg\linalg.py:1623, in svd(a, full_matrices, compute_uv, hermitian)
       1620         s = abs(s)
       1621         return sort(s)[..., ::-1]
    -> 1623 _assert_stacked_2d(a)
       1624 t, result_t = _commonType(a)
       1626 extobj = get_linalg_error_extobj(_raise_linalgerror_svd_nonconvergence)
    
    File ~\miniconda3\lib\site-packages\numpy\linalg\linalg.py:183, in _assert_stacked_2d(*arrays)
        181 for a in arrays:
        182     if a.ndim < 2:
    --> 183         raise LinAlgError('%d-dimensional array given. Array must be '
        184                 'at least two-dimensional' % a.ndim)
    
    LinAlgError: 1-dimensional array given. Array must be at least two-dimensional
    

    `2xn dimension' is poor paraphrase of this error.

    With a (1,3) argument:

    In [28]: np.linalg.svd([[1,2,3]])
    Out[28]: 
    (array([[-1.]]),
     array([3.74165739]),
     array([[-0.26726124, -0.53452248, -0.80178373],
            [-0.53452248,  0.77454192, -0.33818712],
            [-0.80178373, -0.33818712,  0.49271932]]))
    

    and a (3,1):

    In [29]: np.linalg.svd([[1],[2],[3]])
    Out[29]: 
    (array([[ 0.26726124, -0.53452248, -0.80178373],
            [ 0.53452248,  0.77454192, -0.33818712],
            [ 0.80178373, -0.33818712,  0.49271932]]),
     array([3.74165739]),
     array([[1.]]))
    

    If you already have a 1 dimensional array, arr[:,None] or arr.reshape(-1,1) will change it to (n,1) shape.