Numpy array and Matlab Matrix are mismatching [3D]

前端 未结 5 1460
失恋的感觉
失恋的感觉 2021-01-06 17:32

The following octave code shows a sample 3D matrix using Octave/Matlab

octave:1> A=zeros(3,3,3);
octave:2> 
octave:2> A(:,:,1)= [[1 2 3];[4 5 6];[7         


        
相关标签:
5条回答
  • 2021-01-06 17:54

    I think that python uses this type of indexing to create arrays as shown in the following figure:

    https://www.google.com.eg/search?q=python+indexing+arrays+numpy&biw=1555&bih=805&source=lnms&tbm=isch&sa=X&ved=0ahUKEwia7b2J1qzOAhUFPBQKHXtdCBkQ_AUIBygC#imgrc=7JQu1w_4TCaAnM%3A

    And, there are many ways to store your data, you can choose order='F' to count the columns first as matlab does, while the default is order='C' that count the rows first....

    0 讨论(0)
  • 2021-01-06 17:55

    MATLAB and Python index differently. To investigate this, lets create a linear array of number 1 to 8 and then reshape the result to be a 2-by-2-by-2 matrix in each language:

    MATLAB:

    M_flat = 1:8
    M = reshape(M_flat, [2,2,2])
    

    which returns

    M =
    
    ans(:,:,1) =
    
       1   3
       2   4
    
    ans(:,:,2) =
    
       5   7
       6   8
    

    Python:

    import numpy as np
    P_flat = np.array(range(1,9))
    P = np.reshape(P, [2,2,2])
    

    which returns

    array([[[1, 2],
            [3, 4]],
    
           [[5, 6],
            [7, 8]]])
    

    The first thing you should notice is that the first two dimensions have switched. This is because MATLAB uses column-major indexing which means we count down the columns first whereas Python use row-major indexing and hence it counts across the rows first.

    Now let's try indexing them. So let's try slicing along the different dimensions. In MATLAB, I know to get a slice out of the third dimension I can do

    M(:,:,1)
    
    ans =
    
       1   3
       2   4
    

    Now let's try the same in Python

    P[:,:,0]
    
    array([[1, 3],
           [5, 7]])
    

    So that's completely different. To get the MATLAB 'equivalent' we need to go

    P[0,:,:]
    
    array([[1, 2],
           [3, 4]])
    

    Now this returns the transpose of the MATLAB version which is to be expected due the the row-major vs column-major difference.

    So what does this mean for indexing? It looks like Python puts the major index at the end which is the reverse of MALTAB.

    Let's say I index as follows in MATLAB

    M(1,2,2)
    
    ans = 
    
        7
    

    now to get the 7 from Python we should go

    P(1,1,0)
    

    which is the MATLAB syntax reversed. Note that is is reversed because we created the Python matrix with a row-major ordering in mind. If you create it as you did in your code you would have to swap the last 2 indices so rather create the matrix correctly in the first place as Ander has suggested in the comments.

    0 讨论(0)
  • 2021-01-06 18:02

    I think better than just calling the difference "row major" or "column major" is numpy's way of describing them:

    ‘C’ means to read / write the elements using C-like index order, with the last axis index changing fastest, back to the first axis index changing slowest. ‘F’ means to read / write the elements using Fortran-like index order, with the first index changing fastest, and the last index changing slowest.

    Some gifs to illustrate the difference: The first is row-major (python / c), second is column-major (MATLAB/ Fortran)

    0 讨论(0)
  • 2021-01-06 18:06

    The way your array is constructed in numpy is different than it is in MATLAB.

    Where your MATLAB array is (y, x, z), your numpy array is (z, y, x). Your 3d numpy array is a series of 'stacked' 2d arrays, so you're indexing "outside->inside" (for lack of a better term). Here's your array definition expanded so this (hopefully) makes a little more sense:

    [[[1, 2, 3],
      [4, 5, 6],        # Z = 0
      [7 ,8 ,9]],
     [[11 ,22 ,33],
      [44 ,55 ,66],     # Z = 1
      [77 ,88 ,99]],
     [[111 ,222 ,333],
      [444 ,555 ,666],  # Z = 2
      [777 ,888 ,999]]
    ]
    

    So with:

    import numpy as np
    
    A = np.array([[[1 ,2 ,3],[4 ,5 ,6],[7 ,8 ,9]], [[11 ,22 ,33],[44 ,55 ,66],[77 ,88 ,99]], [[111 ,222 ,333],[444 ,555 ,666],[777 ,888 ,999]]])
    B = A[1, 0, 2]
    

    B returns 33, as expected.

    If you want a less mind-bending way to indexing your array, consider generating it as you did in MATLAB.

    0 讨论(0)
  • 2021-01-06 18:06

    I think that the problem is the way you create the matrix in numpy and also the different representation of matlab and numpy, why you don't use the same system in matlab and numpy

    >>> A = np.zeros((3,3,3),dtype=int)
    >>> A
    array([[[0, 0, 0],
            [0, 0, 0],
            [0, 0, 0]],
    
           [[0, 0, 0],
            [0, 0, 0],
            [0, 0, 0]],
    
           [[0, 0, 0],
            [0, 0, 0],
            [0, 0, 0]]])
    >>> A[:,:,0] = np.array([[1,2,3],[4,5,6],[7,8,9]])
    >>> A[:,:,1] = np.array([[11,22,33],[44,55,66],[77,88,99]])
    >>> A[:,:,2] = np.array([[111,222,333],[444,555,666],[777,888,999]])
    >>> A
    array([[[  1,  11, 111],
            [  2,  22, 222],
            [  3,  33, 333]],
    
           [[  4,  44, 444],
            [  5,  55, 555],
            [  6,  66, 666]],
    
           [[  7,  77, 777],
            [  8,  88, 888],
            [  9,  99, 999]]])
    >>> A[0,2,1]
    33
    
    0 讨论(0)
提交回复
热议问题