我有oldMat
这是股票代码的排名。列号表示相应的等级,例如第一列等于最高等级,第二列等于第二高等级,依此类推。 oldMat
中的整数表示个人股票代码的数量。 3
中的数字oldMat(3,2,1)
表示第三个股票代码在第三个时期排名第二(行代表不同的时期)。
现在,我需要通过以下方式转换oldMat
:列号现在代表各个股票代码。整数现在代表个别股票代码在特定时期持有的等级。例如,2
中的数字newMat(3,3,1)
表示第三个股票代码在第三个时期排名第二。
我使用for循环来解决这个问题,但我很确定存在一种更有效的方法来实现这个结果。这是我的代码:
% Define oldMat
oldMat(:,:,1) = ...
[NaN, NaN, NaN, NaN, NaN, NaN; ...
1, 3, 4, 6, 2, 5; ...
6, 3, 4, 1, 2, 5; ...
2, 3, 6, 1, 4, 5; ...
5, 4, 6, 2, 3, 1; ...
5, 1, 2, 3, 6, 4; ...
4, 5, 1, 3, 6, 2; ...
4, 1, 6, 5, 2, 3];
oldMat(:,:,2) = ...
[NaN, NaN, NaN, NaN, NaN, NaN; ...
NaN, NaN, NaN, NaN, NaN, NaN; ...
1, 6, 3, 4, 2, 5; ...
6, 3, 2, 1, 4, 5; ...
2, 6, 3, 4, 1, 5; ...
5, 2, 1, 6, 3, 4; ...
5, 1, 3, 6, 2, 4; ...
4, 1, 5, 6, 3, 2];
% Pre-allocate newMat
newMat = nan(size(oldMat));
% Transform oldMat to newMat
for runNum = 1 : size(newMat,3)
for colNum = 1 : size(newMat,2)
for rowNum = 1 : size(newMat,1)
if ~isnan(oldMat(rowNum, colNum, runNum))
newMat(rowNum,oldMat(rowNum, colNum, runNum), runNum) = colNum;
end
end
end
end
答案 0 :(得分:2)
看起来像sub2ind
的经典案例。您想要创建一组线性索引来访问新矩阵的第二个维度,并将其设置为等于列号。首先使用meshgrid
创建一个3D坐标网格,然后使用oldMat
矩阵作为输出第二列的索引,并将其设置为等于列编号。确保您不会复制任何NaN
个值,否则sub2ind
会抱怨。您可以使用isnan
来帮助过滤这些值:
% Initialize new matrix
newMat = nan(size(oldMat));
% Generate a grid of coordinates
[X,Y,Z] = meshgrid(1:size(newMat,2), 1:size(newMat,1), 1:size(newMat,3));
% Find elements that are NaN and remove
mask = isnan(oldMat);
X(mask) = []; Y(mask) = []; Z(mask) = [];
% Set the values now
newMat(sub2ind(size(oldMat), Y, oldMat(~isnan(oldMat)).', Z)) = X;