为 MATLAB 要求兼容性重塑 3D numpy 数组
Reshaping 3D numpy array for MATLAB requirement compatibility
给定一个形状数组 3,2,2
np.array([[[1,2],[3,4]],[[5,6],[7,8]],[[9,10],[11,12]]])
我想把它改造成2,2,3
的形状。
下游,这个重塑数据将在 MATLAB 中处理,出于某种原因,MATLAB 包需要对数组进行整形 2,2,3
。
在 MATLAB 中,预期的输出应该是
val(:,:,1) =
1 2
3 4
val(:,:,2) =
5 6
7 8
val(:,:,3) =
9 10
11 12
简单地重塑 arr.reshape(2,2,3)
并没有产生我想要的效果。
更新:
提出提案
val(:,:,1) =
1 3
2 4
val(:,:,2) =
5 7
6 8
val(:,:,3) =
9 11
10 12
In [29]: arr = np.array([[[1,2],[3,4]],[[5,6],[7,8]],[[9,10],[11,12]]])
In [30]: arr
Out[30]:
array([[[ 1, 2],
[ 3, 4]],
[[ 5, 6],
[ 7, 8]],
[[ 9, 10],
[11, 12]]])
In [31]: arr.shap
Out[31]: (3, 2, 2)
MATLAB 存储类似于 numpy 的阶 'F' 的矩阵,尾随维度最外层。使用 2d 作为转置最容易将其可视化。让我们在 3d 上试试看:
In [32]: arr1 = arr.T
In [33]: arr1.shape
Out[33]: (2, 2, 3)
In [34]: arr1
Out[34]:
array([[[ 1, 5, 9],
[ 3, 7, 11]],
[[ 2, 6, 10],
[ 4, 8, 12]]])
MATLAB 通过在最后一个维度上迭代显示 3d 数组,它的“平面”:
In [36]: for i in range(3):print(arr1[:,:,i])
[[1 3]
[2 4]]
[[5 7]
[6 8]]
[[ 9 11]
[10 12]]
我没有你的 MATLAB npy 加载器,但可以探索 io.savemat/loadmat
如何进行传输。这适用于 MATLAB 格式的文件:
In [37]: from scipy import io
In [38]: io.savemat('test3d.mat',{'arr':arr, 'arr1':arr1})
In [39]: io.loadmat('test3d.mat')
Out[39]:
{'__header__': b'MATLAB 5.0 MAT-file Platform: posix, Created on: Sun Dec 5 08:29:25 2021',
'__version__': '1.0',
'__globals__': [],
'arr': array([[[ 1, 2],
[ 3, 4]],
[[ 5, 6],
[ 7, 8]],
[[ 9, 10],
[11, 12]]]),
'arr1': array([[[ 1, 5, 9],
[ 3, 7, 11]],
[[ 2, 6, 10],
[ 4, 8, 12]]])}
在 Octave 会话中:
>> load test3d.mat
>> arr
arr =
ans(:,:,1) =
1 3
5 7
9 11
ans(:,:,2) =
2 4
6 8
10 12
>> arr1
arr1 =
ans(:,:,1) =
1 3
2 4
ans(:,:,2) =
5 7
6 8
ans(:,:,3) =
9 11
10 12
并且混乱的显示表明转置保留了原始的 numpy
数据值顺序:
>> arr1(:)'
ans =
1 2 3 4 5 6 7 8 9 10 11 12
>> arr(:)'
ans =
1 5 9 3 7 11 2 6 10 4 8 12
另一种转置将 3 移动到末尾,但保持前 2 的顺序
In [40]: arr2 = arr.transpose(1,2,0)
In [41]: arr2
Out[41]:
array([[[ 1, 5, 9],
[ 2, 6, 10]],
[[ 3, 7, 11],
[ 4, 8, 12]]])
In [42]: for i in range(3):print(arr2[:,:,i])
[[1 2]
[3 4]]
[[5 6]
[7 8]]
[[ 9 10]
[11 12]]
我相信您正在寻找:
np.moveaxis(x, 0, 2)
你原来的形状是(3, 2, 2)。此行移动轴 [0] 并将其滚动到轴 [2](将其他 2 个轴向左移动)。所以你得到:
>>> x[:, :, 0]
array([[1, 2],
[3, 4]])
给定一个形状数组 3,2,2
np.array([[[1,2],[3,4]],[[5,6],[7,8]],[[9,10],[11,12]]])
我想把它改造成2,2,3
的形状。
下游,这个重塑数据将在 MATLAB 中处理,出于某种原因,MATLAB 包需要对数组进行整形 2,2,3
。
在 MATLAB 中,预期的输出应该是
val(:,:,1) =
1 2
3 4
val(:,:,2) =
5 6
7 8
val(:,:,3) =
9 10
11 12
简单地重塑 arr.reshape(2,2,3)
并没有产生我想要的效果。
更新:
val(:,:,1) =
1 3
2 4
val(:,:,2) =
5 7
6 8
val(:,:,3) =
9 11
10 12
In [29]: arr = np.array([[[1,2],[3,4]],[[5,6],[7,8]],[[9,10],[11,12]]])
In [30]: arr
Out[30]:
array([[[ 1, 2],
[ 3, 4]],
[[ 5, 6],
[ 7, 8]],
[[ 9, 10],
[11, 12]]])
In [31]: arr.shap
Out[31]: (3, 2, 2)
MATLAB 存储类似于 numpy 的阶 'F' 的矩阵,尾随维度最外层。使用 2d 作为转置最容易将其可视化。让我们在 3d 上试试看:
In [32]: arr1 = arr.T
In [33]: arr1.shape
Out[33]: (2, 2, 3)
In [34]: arr1
Out[34]:
array([[[ 1, 5, 9],
[ 3, 7, 11]],
[[ 2, 6, 10],
[ 4, 8, 12]]])
MATLAB 通过在最后一个维度上迭代显示 3d 数组,它的“平面”:
In [36]: for i in range(3):print(arr1[:,:,i])
[[1 3]
[2 4]]
[[5 7]
[6 8]]
[[ 9 11]
[10 12]]
我没有你的 MATLAB npy 加载器,但可以探索 io.savemat/loadmat
如何进行传输。这适用于 MATLAB 格式的文件:
In [37]: from scipy import io
In [38]: io.savemat('test3d.mat',{'arr':arr, 'arr1':arr1})
In [39]: io.loadmat('test3d.mat')
Out[39]:
{'__header__': b'MATLAB 5.0 MAT-file Platform: posix, Created on: Sun Dec 5 08:29:25 2021',
'__version__': '1.0',
'__globals__': [],
'arr': array([[[ 1, 2],
[ 3, 4]],
[[ 5, 6],
[ 7, 8]],
[[ 9, 10],
[11, 12]]]),
'arr1': array([[[ 1, 5, 9],
[ 3, 7, 11]],
[[ 2, 6, 10],
[ 4, 8, 12]]])}
在 Octave 会话中:
>> load test3d.mat
>> arr
arr =
ans(:,:,1) =
1 3
5 7
9 11
ans(:,:,2) =
2 4
6 8
10 12
>> arr1
arr1 =
ans(:,:,1) =
1 3
2 4
ans(:,:,2) =
5 7
6 8
ans(:,:,3) =
9 11
10 12
并且混乱的显示表明转置保留了原始的 numpy
数据值顺序:
>> arr1(:)'
ans =
1 2 3 4 5 6 7 8 9 10 11 12
>> arr(:)'
ans =
1 5 9 3 7 11 2 6 10 4 8 12
另一种转置将 3 移动到末尾,但保持前 2 的顺序
In [40]: arr2 = arr.transpose(1,2,0)
In [41]: arr2
Out[41]:
array([[[ 1, 5, 9],
[ 2, 6, 10]],
[[ 3, 7, 11],
[ 4, 8, 12]]])
In [42]: for i in range(3):print(arr2[:,:,i])
[[1 2]
[3 4]]
[[5 6]
[7 8]]
[[ 9 10]
[11 12]]
我相信您正在寻找:
np.moveaxis(x, 0, 2)
你原来的形状是(3, 2, 2)。此行移动轴 [0] 并将其滚动到轴 [2](将其他 2 个轴向左移动)。所以你得到:
>>> x[:, :, 0]
array([[1, 2],
[3, 4]])