编写可在Matlab中读取的3D Numpy数组 [英] Writing a 3d numpy array that is readable in matlab

查看:88
本文介绍了编写可在Matlab中读取的3D Numpy数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将3D numpy数组保存到磁盘上,以便以后可以在matlab中读取它.在3D数组上使用numpy.savetxt()时遇到了一些困难,因此我的解决方案是先使用以下代码将其转换为1D数组:

I'm trying to save a 3D numpy array to my disk so that I can later read it in matlab. I've had some difficulty using numpy.savetxt() on a 3D array, so my solution has been to first convert it to a 1D array using the following code:

import numpy

array = numpy.array([[0, 1, 2, 3],
       [0, 1, 1, 3],
       [3, 1, 3, 1]])

ndarray = numpy.dstack((array, array, array))

darray = ndarray.reshape(36,1)

numpy.savetxt('test.txt', darray, fmt = '%i')

然后在matlab中,可以使用以下代码进行读取:

Then in matlab it can be read with the following code:

file = fopen('test.txt')
array = fscanf(file, '%f')

我现在的问题是将其转换回原始形状.使用reshape(array, 3,4,3)会产生以下结果:

My issue now is converting it back to the original shape. Using reshape(array, 3,4,3) yields the following:

ans(:,:,1) =

     0     1     2     3
     0     1     2     3
     0     1     2     3


ans(:,:,2) =

     0     1     1     3
     0     1     1     3
     0     1     1     3


ans(:,:,3) =

     3     1     3     1
     3     1     3     1
     3     1     3     1

我尝试转置1D matlab数组,然后使用reshape()但得到相同的数组.

I've tried to transpose the 1D matlab array, then use reshape() but get the same array.

我可以应用什么matlab函数来实现原始的python数组?

What matlab function can I apply to achieve my original python array?

推荐答案

您要permute尺寸.在numpy中,这是transpose.有两个并发症-MATLAB矩阵的"F"阶和显示模式,使用最后一个维度上的块(这是F阶的外部).跳到该答案的末尾以获取详细信息.

You want to permute the dimensions. In numpy this is transpose. There are two complications - the 'F' order of MATLAB matrices, and the display pattern, using blocks on the last dimension (which is the outer one with F order). Jump to the end of this answer for details.

===

In [72]: arr = np.array([[0, 1, 2, 3],
    ...:        [0, 1, 1, 3],
    ...:        [3, 1, 3, 1]])
    ...:        
In [80]: np.dstack((arr,arr+1))
Out[80]: 
array([[[0, 1],
        [1, 2],
        [2, 3],
        [3, 4]],

       [[0, 1],
        [1, 2],
        [1, 2],
        [3, 4]],

       [[3, 4],
        [1, 2],
        [3, 4],
        [1, 2]]])
In [81]: np.dstack((arr,arr+1)).shape
Out[81]: (3, 4, 2)

In [75]: from scipy.io import loadmat, savemat
In [76]: pwd
Out[76]: '/home/paul/mypy'
In [83]: savemat('test3',{'arr':arr, 'arr3':arr3})

在八度音阶中

>> load 'test3.mat'
>> arr
arr =

  0  1  2  3
  0  1  1  3
  3  1  3  1

>> arr3
arr3 =

ans(:,:,1) =

  0  1  2  3
  0  1  1  3
  3  1  3  1

ans(:,:,2) =

  1  2  3  4
  1  2  2  4
  4  2  4  2

>> size(arr3)
ans =

   3   4   2

回到numpy中,我可以使用以下命令将数组显示为2个3x4块:

back in numpy I can display the array as 2 3x4 blocks with:

In [95]: arr3[:,:,0]
Out[95]: 
array([[0, 1, 2, 3],
       [0, 1, 1, 3],
       [3, 1, 3, 1]])
In [96]: arr3[:,:,1]
Out[96]: 
array([[1, 2, 3, 4],
       [1, 2, 2, 4],
       [4, 2, 4, 2]])

这些数组的大小为1d(实际上显示了基础数据缓冲区中值的布局):

These arrays, ravelled to 1d (showing in effect the layout of values in the underlying databuffer):

In [100]: arr.ravel()
Out[100]: array([0, 1, 2, 3, 0, 1, 1, 3, 3, 1, 3, 1])
In [101]: arr3.ravel()
Out[101]: 
array([0, 1, 1, 2, 2, 3, 3, 4, 0, 1, 1, 2, 1, 2, 3, 4, 3, 4, 1, 2, 3, 4, 1, 2])

相应的八度音阶:

>> arr(:).'
ans =
  0  0  3  1  1  1  2  1  3  3  3  1

>> arr3(:).'
ans =
  0  0  3  1  1  1  2  1  3  3  3  1  1  1  4  2  2  2  3  2  4  4  4  2

MATLAB使用F(fortran)顺序,第一维的变化最快.因此,显示块arr(:,:i)是很自然的.您可以在创建和使用numpy数组时指定order='F'.但是,要保持顺序整齐可能会很棘手,尤其是在使用3d时. loadmat/savemat尝试为我们进行一些重新排序.例如,二维MATLAB矩阵在numpy中作为F数组加载.

MATLAB uses F (fortran) order, with the first dimension changing fastest. Thus it is natural to display blocks arr(:,:i). You can specify order='F' when creating and working with numpy arrays. But it can be tricky keeping the order straight, especially when working with 3d. loadmat/savemat try to do some of the reordering for us. For example a 2d MATLAB matrix loads as an order F array in numpy.

In [107]: np.array([0,0,3,1,1,1,2,1,3,3,3,1])
Out[107]: array([0, 0, 3, 1, 1, 1, 2, 1, 3, 3, 3, 1])
In [108]: np.array([0,0,3,1,1,1,2,1,3,3,3,1]).reshape(4,3)
Out[108]: 
array([[0, 0, 3],
       [1, 1, 1],
       [2, 1, 3],
       [3, 3, 1]])
In [109]: np.array([0,0,3,1,1,1,2,1,3,3,3,1]).reshape(4,3).T
Out[109]: 
array([[0, 1, 2, 3],
       [0, 1, 1, 3],
       [3, 1, 3, 1]])
In [111]: np.array([0,0,3,1,1,1,2,1,3,3,3,1]).reshape((3,4),order='F')
Out[111]: 
array([[0, 1, 2, 3],
       [0, 1, 1, 3],
       [3, 1, 3, 1]])


使用此数组跟踪形状可能更容易:


It might easier to keep track of shapes with this array:

In [112]: arr3 = np.arange(2*3*4).reshape(2,3,4)
In [113]: arr3f = np.arange(2*3*4).reshape(2,3,4, order='F')
In [114]: arr3
Out[114]: 
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[12, 13, 14, 15],
        [16, 17, 18, 19],
        [20, 21, 22, 23]]])
In [115]: arr3f
Out[115]: 
array([[[ 0,  6, 12, 18],
        [ 2,  8, 14, 20],
        [ 4, 10, 16, 22]],

       [[ 1,  7, 13, 19],
        [ 3,  9, 15, 21],
        [ 5, 11, 17, 23]]])
In [116]: arr3f.ravel()
Out[116]: 
array([ 0,  6, 12, 18,  2,  8, 14, 20,  4, 10, 16, 22,  1,  7, 13, 19,  3,
        9, 15, 21,  5, 11, 17, 23])
In [117]: arr3f.ravel(order='F')
Out[117]: 
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23])
In [118]: savemat('test3',{'arr3':arr3, 'arr3f':arr3f})

在八度音阶中:

>> arr3
arr3 =
ans(:,:,1) =
   0   4   8
  12  16  20

ans(:,:,2) =
   1   5   9
  13  17  21
....
>> arr3f
arr3f =
ans(:,:,1) =
   0   2   4
   1   3   5

ans(:,:,2) =
   6   8  10
   7   9  11
...
>> arr3.ravel()'
error: int32 matrix cannot be indexed with .
>> arr3(:)'
ans =
 Columns 1 through 20:
   0  12   4  16   8  20   1  13   5  17   9  21   2  14   6  18  10  22   3  15
 Columns 21 through 24:
   7  19  11  23
>> arr3f(:)'
ans =
 Columns 1 through 20:
   0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19
 Columns 21 through 24:
  20  21  22  23

arr3f由块打印时,看起来仍然是'messedup',但是当被弄乱时,我们看到值是相同的F顺序.如果我们打印numpy数组的最后一个块",这也很明显:

arr3f still looks 'messedup' when printed by blocks, but when raveled we see that values are in same F order. That's also evident if we print the last 'block' of the numpy array:

In [119]: arr3f[:,:,0]
Out[119]: 
array([[0, 2, 4],
       [1, 3, 5]])

因此,要匹配numpy和matlab,我们必须保持两件事-顺序和块显示样式.

So to match up numpy and matlab we have to keep 2 things straight - the order, and the block display style.

我的MATLAB生锈了,但是我发现permutenp.transpose类似.使用它来重新排列尺寸:

My MATLAB is rusty, but I found permute with is similar to the np.transpose. Using that to reorder the dimensions:

>> permute(arr3,[3,2,1])
ans =
ans(:,:,1) =
   0   4   8
   1   5   9
   2   6  10
   3   7  11

ans(:,:,2) =
  12  16  20
  13  17  21
  14  18  22
  15  19  23
>> permute(arr3,[3,2,1])(:)'
ans =
 Columns 1 through 20:
   0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19
 Columns 21 through 24:
  20  21  22  23

numpy

In [121]: arr3f.transpose(2,1,0).ravel()
Out[121]: 
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23])

(对不起,答案很抱歉.我可能会对其进行编辑.希望它能为您提供一些帮助.)

(Sorry for the rambling answer. I may go back an edit it. Hopefully it gives you something to work with.)

===

让我们尝试将杂乱无章的内容更具体地应用于您的案例

Let's try to apply that rambling more explicitly to your case

In [122]: x = np.array([[0, 1, 2, 3],
     ...:        [0, 1, 1, 3],
     ...:        [3, 1, 3, 1]])
     ...:        
In [123]: x3 = np.dstack((x,x,x))
In [125]: dx3 = x3.reshape(36,1)
In [126]: np.savetxt('test3.txt',dx3, fmt='%i')
In [127]: cat test3.txt
0
0
0
....
3
3
1
1
1

在八度音阶中

>> file = fopen('test3.txt')
file =  21
>> array = fscanf(file,'%f')
array =
   0
   0
   ....

>> reshape(array,3,4,3)
ans =
ans(:,:,1) =
   0   1   2   3
   0   1   2   3
   0   1   2   3
ans(:,:,2) =
   0   1   1   3
   0   1   1   3
   0   1   1   3
ans(:,:,3) =
   3   1   3   1
   3   1   3   1
   3   1   3   1

并伴随着渗透

>> permute(reshape(array,3,4,3),[3,2,1])
ans =
ans(:,:,1) =
   0   1   2   3
   0   1   1   3
   3   1   3   1
ans(:,:,2) =
   0   1   2   3
   0   1   1   3
   3   1   3   1
ans(:,:,3) =
   0   1   2   3
   0   1   1   3
   3   1   3   1

这篇关于编写可在Matlab中读取的3D Numpy数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆