说我有一个项目ID的矢量A
:
A=[50936
332680
107430
167940
185820
99732
198490
201250
27626
69375];
我有一个矩阵B
,其行包含向量A
中每个项目的8个参数值:
B=[0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 0 1 0 0 1 0 1 1 1
1 0 1 0 0 1 0 1 1 1
0 0 1 0 0 0 0 1 0 1
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1];
因此,矩阵B
中的第1列表示向量A
的第1行中的项目数据,矩阵B
中的第2列表示向量{{1的第2行中的项目数据}}, 等等。但是,我希望矩阵A
包含存储在向量B
中的不同项目顺序的信息:
A2
如何对它们进行排序,以便矩阵A2=[185820
198490
69375
167940
99732
332680
27626
107430
50936
201250];
的第1列包含向量B
第1行中项目的数据,矩阵A2
的第2列包含行中项目的数据向量B
的2,依此类推?
我这样做非常粗糙的解决方案如下:
A2
但我想知道更清洁,更优雅,更省时的方法。
答案 0 :(得分:6)
可能的解决方案
您可以使用ismember
函数的第二个输出。
[~ ,idx] = ismember(A2,A);
B2 = B(:,idx);
更新:我测试了我的解决方案和hbaderts
提出的另一个解决方案disp('-----ISMEMBER:-------')
tic
[~,idx]=ismember(A2,A);
toc
disp('-----SORT:-----------')
tic
[~,idx1] = sort(A);
[~,idx2] = sort(A2);
map = zeros(1,size(idx2));
map(idx2) = idx1;
toc
以下是Octave中的结果:
-----ISMEMBER:-------
Elapsed time is 0.00157714 seconds.
-----SORT:-----------
Elapsed time is 4.41074e-05 seconds.
结论:排序方法效率更高!
答案 1 :(得分:4)
由于A
和A2
包含完全相同的元素,只是排序不同,我们可以创建从A
- 排序到A2
- 排序的映射。为此,我们在两者上运行https://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.110).aspx函数并保存索引(这是第二个输出)。
[~,idx1] = sort(A);
[~,idx2] = sort(A2);
现在,idx1
中的第一个元素对应idx2
中的第一个元素,因此A(idx1(1))
与A2(idx2(1))
相同(即27626)。要创建映射idx1 -> idx2
,我们使用矩阵索引如下
map = zeros(size(idx2));
map(idx2) = idx1;
要相应地排序B
,我们需要做的就是
B2 = B(:, map);
答案 2 :(得分:0)
[A2, sort_order] = sort(A);
B2 = B(:, sort_order)
MATLAB的排序函数返回A中项目的排序顺序。您可以使用它来订购B中的列。
答案 3 :(得分:0)
转置B
,以便您可以将其与A
:
C = [A B']
现在你有了
C = [ 50936 0 0 1 1 0 0 0 0;
332680 0 0 0 0 0 0 0 0;
107430 0 0 1 1 1 0 0 0;
167940 0 0 0 0 0 0 0 0;
185820 0 0 0 0 0 0 0 0;
99732 0 0 1 1 0 0 0 0;
198490 0 0 0 0 0 0 0 0;
201250 0 0 1 1 1 1 0 0;
27626 0 0 1 1 0 0 0 0;
69375 0 0 1 1 1 0 0 1];
您现在可以根据需要对矩阵的行进行排序。例如,要按ID按升序排序,请使用sortrows
:
C = sortrows(C)
要仅交换行,请使用1:length(A)
:
C = C(perm, :)
其中perm
可能类似于[4 5 6 3 2 1 8 7 9 10]
。
这样,您的信息全部包含在一个结构中,并且数据始终与正确的ID正确匹配。