简体   繁体   English

Numpy数组和Matlab矩阵不匹配[3D]

[英]Numpy array and Matlab Matrix are mismatching [3D]

The following octave code shows a sample 3D matrix using Octave/Matlab 以下八度音程代码使用Octave / Matlab显示示例3D矩阵

octave:1> A=zeros(3,3,3);
octave:2> 
octave:2> A(:,:,1)= [[1 2 3];[4 5 6];[7 8 9]];
octave:3> 
octave:3> A(:,:,2)= [[11 22 33];[44 55 66];[77 88 99]];
octave:4> 
octave:4> A(:,:,3)= [[111 222 333];[444 555 666];[777 888 999]];
octave:5> 
octave:5> 
octave:5> A
A =

ans(:,:,1) =

   1   2   3
   4   5   6
   7   8   9

ans(:,:,2) =

   11   22   33
   44   55   66
   77   88   99

ans(:,:,3) =

   111   222   333
   444   555   666
   777   888   999

octave:6> A(1,3,2)
ans =  33

And I need to convert the same matrix using numpy ... unfortunately When I'm trying to access the same index using array in numpy I get different values as shown below!! 我需要使用numpy转换相同的矩阵...不幸的是当我尝试使用numpy中的数组访问相同的索引时,我得到不同的值,如下所示!

import numpy as np
array = 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]]])
>>> array[0,2,1]
8

Also I read the following document that shows the difference between matrix implementation in Matlab and in Python numpy Numpy for Matlab users but I didn't find a sample 3d array and the mapping of it into Matlab and vice versa! 我还阅读了以下文档,该文档显示了Matlab中的矩阵实现与Matlab用户的 Python numpy Numpy之间的区别,但我没有找到示例3d数组并将其映射到Matlab,反之亦然!

the answer is different for example accessing the element(1,3,2) in Matlab doesn't match the same index using numpy (0,2,1) 答案是不同的,例如在Matlab中访问元素(1,3,2)与使用numpy(0,2,1)的相同索引不匹配

Octave/Matlab 八度/ Matlab的

octave:6> A(1,3,2) 八度:6> A(1,3,2)

ans = 33 ans = 33

Python 蟒蛇

>>> array[0,2,1] >>>数组[0,2,1]

8 8

The way your array is constructed in numpy is different than it is in MATLAB. 你的数组在numpy中构造的方式与在MATLAB中的不同。

Where your MATLAB array is (y, x, z) , your numpy array is (z, y, x) . 你的MATLAB数组是(y, x, z) ,你的numpy数组是(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). 你的3d numpy数组是一系列“堆叠”的2d数组,所以你要将“outside-> inside”编入索引(因为没有更好的术语)。 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. B按预期返回33

If you want a less mind-bending way to indexing your array, consider generating it as you did in MATLAB. 如果您想要一种不那么令人费解的方法来索引数组,请考虑像在MATLAB中那样生成它。

MATLAB and Python index differently. MATLAB和Python索引不同。 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: 为了研究这个问题,让我们创建一个数字18的线性数组,然后将结果reshape整形为每种语言的2 by- 2 by- 2矩阵:

MATLAB: 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. 这是因为MATLAB使用列主索引,这意味着我们首先倒数列,而Python使用行主索引,因此它首先计算行数。

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 在MATLAB中,我知道可以从第三维中获得切片

M(:,:,1)

ans =

   1   3
   2   4

Now let's try the same in Python 现在让我们在Python中尝试相同的操作

P[:,:,0]

array([[1, 3],
       [5, 7]])

So that's completely different. 所以这完全不同。 To get the MATLAB 'equivalent' we need to go 要获得MATLAB“等效”,我们需要去

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. 现在,这将返回MATLAB版本的转置,这是由于行主要与列主要差异所预期的。

So what does this mean for indexing? 那么这对于索引是什么意思呢? It looks like Python puts the major index at the end which is the reverse of MALTAB. 看起来Python将主要索引放在最后,这与MALTAB 相反

Let's say I index as follows in MATLAB 假设我在MATLAB中索引如下

M(1,2,2)

ans = 

    7

now to get the 7 from Python we should go 现在要从Python中获取7 ,我们应该去

P(1,1,0)

which is the MATLAB syntax reversed. 这是MATLAB语法颠倒过来的。 Note that is is reversed because we created the Python matrix with a row-major ordering in mind. 请注意,这是相反的,因为我们创建了Python矩阵,并考虑了行主要排序。 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. 如果你像在代码中那样创建它,则必须交换最后2个索引,而不是像Ander在评论中建议的那样首先正确地创建矩阵。

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 我认为问题是你在numpy中创建矩阵的方式以及matlab和numpy的不同表示,为什么你不在matlab和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

I think better than just calling the difference "row major" or "column major" is numpy's way of describing them: 我认为不仅仅是调用差异“行主要”或“列专业”是numpy描述它们的方式:

'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. “C”表示使用类似C的索引顺序读取/写入元素,最后一个轴索引变化最快,返回到第一个轴索引变化最慢。 'F' means to read / write the elements using Fortran-like index order, with the first index changing fastest, and the last index changing slowest. 'F'表示使用类似Fortran的索引顺序读/写元素,第一个索引变化最快,最后一个索引变化最慢。

Some gifs to illustrate the difference: The first is row-major (python / c), second is column-major (MATLAB/ Fortran) 一些GIF来说明差异:第一个是行主要(python / c),第二个是列主要(MATLAB / Fortran)

Python / C索引排序

MATLAB / Fortran索引排序

I think that python uses this type of indexing to create arrays as shown in the following figure: 我认为python使用这种类型的索引来创建数组,如下图所示:

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 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.... 并且,有很多方法可以存储您的数据,您可以选择order ='F'来首先按照matlab计算列,而默认值是order ='C',它首先计算行数....

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM