假設A
是輸入單元陣列,這裏可能有兩種方法。
方法#1
%// Initlialize output array
Aout = cell(size(A));
for k = 1:size(A,2)
%// Select one column
Ak = A(:,k);
%// Logical array with size of Ak and ones at places with non-empty strings
pos = cellfun(@(x) ~isempty(x), Ak);
%// Find unique strings and find indices for all places in that column
%// with respect to those unique strings
[unq_str,~,str_idx] = unique(Ak,'stable');
%// Perform cumsum on pos to get an array with a "stepped" array that
%// steps up at each non-empty string position.
%// Then replace each stepping number with the string IDs
idx = changem(cumsum(pos),str_idx(pos),1:sum(pos));
%// Index into each column with those replaced IDs for the final output
Aout(:,k) = unq_str(idx);
end
與輸入稍微改變了一下更加積極地測試出該解決方案的代碼,我們不得不代碼運行後 -
A =
'a' 'b'
'' ''
'' 'a'
'c' ''
'' 'd'
'a' ''
'' 'f'
'c' 'a'
Aout =
'a' 'b'
'a' 'b'
'a' 'a'
'c' 'a'
'c' 'd'
'a' 'd'
'a' 'f'
'c' 'a'
方法#2 [小巧,也許更高效]
您可以輸入單元陣列重塑成一個單一的圓柱電池陣列,因此您將無法通過 單元陣列的列需要循環,這可能導致更高效和緊湊的代碼 -
%// Reshape all cells into a single columned cell array
A1 = A(:);
%// Rest of the code borrowed from previous approach with reshaping added
%// at the end to bring the output back to the size of input array
pos = ~cellfun('isempty', A1);
[unq_str,~,str_idx] = unique(A1,'stable');
Aout = reshape(unq_str(changem(cumsum(pos),str_idx(pos),1:sum(pos))),size(A));
獎勵:定製化實施的changem
前面列出的代碼使用changem
需要Mapping Toolbox
。所以,如果你確實有這個問題,這裏有一個定製的版本,用bsxfun
和max
實現,並且僅僅是早期解決方案代碼here的拋光版本。這裏去自定義函數代碼 -
%// CHANGEM_CUSTOM Home-cooked vesion of CHANGEM with MAX, BSXFUN
function A = changem_custom(A,newvals,oldvals)
[valid,id] = max(bsxfun(@eq,A(:),oldvals(:).'),[],2); %//'
A(valid) = newvals(id(valid));
return;
因此,要使用這個自定義函數替換changem
,只是在前面的代碼替換函數調用的名字在那裏。
優秀。感謝您的解決方案。今天,我學習了新的功能「changem」。 – nik 2015-01-31 22:46:43
@nik是的!事實上,我之前只看到過一次,所以它對我來說也很新穎! – Divakar 2015-01-31 22:47:21
哇! 'changem'!涼!如果我想要替換矩陣中的多個條目,我總是使用邏輯索引來循環它。很高興知道這裏有一項便利功能。 +1 – rayryeng 2015-02-01 00:36:54