2012-06-14 321 views
1

刪除NaN的我有一個矩陣:MATLAB從矩陣

raw = 

'alon'  'tomer' 'ilana' 'T1'  '2'  '53'  '24'  'NaN' 
'ilana' 'oren'  '6'  'a'  'g'  'g'  'gsh'  'NaN' 
'dikla' 'aba'  'mama'  'a'  'h'  'ghfs' 'bfsbf' 'NaN' 
'4'  'NaN'  'NaN'  'nn' 'NaN' 'NaN'  'hadhd' 'NaN' 

,我想刪除楠獲得:

'alon'  'tomer' 'ilana' 'T1'  '2'  '53'  '24' 
    'ilana' 'oren'  '6'  'a'  'g'  'g'  'gsh' 
    'dikla' 'aba'  'mama'  'a'  'h'  'ghfs' 'bfsbf' 
    '4'   ''  ''   'nn'  ''  ''  'hadhd' 

怎麼做呢?

我嘗試了很多的建議,但我得到的錯誤:

1)

>> raw=raw(~isnan(raw(:,2)),:) 
??? Undefined function or method 'isnan' for input arguments of type 'cell'. 

2)

raw(isnan(raw(:,1)),:) = []; 
??? Undefined function or method 'isnan' for input arguments of type 'cell'. 

3)

raw(~any(isnan(raw),2),:) 
??? Undefined function or method 'isnan' for input arguments of type 'cell'. 

4)

T(cellfun(@isnan,T))={0} 
??? Error using ==> cellfun 
Non-scalar in Uniform output, at index 1, output 1. 
Set 'UniformOutput' to false. 

我試圖安薩里的解決方案,但現在我得到:

raw = 

'alon'  'tomer' 'ilana' 'T1' '2' '53'  '24'  [0] 
'ilana' 'oren'  '6'  'a'  'g' 'g'  'gsh'  [0] 
'dikla' 'aba'  'mama'  'a'  'h' 'ghfs' 'bfsbf' [0] 
'4'  [ 0] [ 0] 'nn' [0] [ 0] 'hadhd' [0] 

這不是爲我好,因爲我想做的事:

size(raw,2) 

,並獲得:

回答

3

像這樣的東西將工作:

f = @(x) strcmp(x, 'NaN'); 
nans = cellfun(f, raw); 
raw(nans) = {''}; %cell(sum(nans(:)), 1); 

isnan只適用於矩陣,所以它不適用於單元陣列。你的NaN似乎也是字符串,而不是真正的NaN。

在這一點上,所有'NaN的將是空字符串。下面將刪除整個行或列空字符串:

raw = raw(:, arrayfun(@(i) length([raw{:, i}]), 1:size(raw, 2)) > 0); % for columns 
raw = raw(arrayfun(@(i) length([raw{i, :}]), 1:size(raw, 1)) > 0, :); % for rows 

對於最後一步,雖然你還不如循環,保持代碼簡潔易懂(和更容易調試!)。你基本上是通過連接字符串來摺疊每行或每列,然後檢查長度是否爲零,以及是否刪除該行或列。

+0

謝謝,我明白了,但是我遇到了一個問題:/我更新了我的主題。 –

+0

對不起,我不明白 - 你有什麼問題?我沒有看到對這個問題所做的任何編輯... – Ansari

+0

我在4分鐘前更新了:] –

1

的備選答案使用regexprep

%示例數據:

raw = { 'alon' 'tomer' 'ilana' 'T1' '2' '53' '24' 'NaN'; 'ilana' 'oren' '6' 'a' 'g' 'g' 'gsh' 'NaN'; 'dikla' 'aba' 'mama' 'a' 'h' 'ghfs' 'bfsbf' 'NaN'; '4' 'NaN' 'NaN' 'nn' 'NaN' 'NaN' 'hadhd' 'NaN' } 

下面的代碼:

output = cellfun(@(x) regexprep(x, 'NaN', ''), raw, 'UniformOutput', false); 
NaNraw = cellfun(@(x) strcmp(x, 'NaN'), raw); 
output(:,all(NaNraw,1)) = []; 

所以,首先raw所有'NaN'串與''替換使用cellfunrepexprep,結果存儲在output。然後邏輯矩陣NaNraw是通過使用cellfunstrcmpraw'NaN'每個字符串比較創建的。最後,刪除output的列,其相應的NaNraw列只包含一列。

output = 
'alon'  'tomer' 'ilana' 'T1' '2' '53'  '24' 
'ilana' 'oren'  '6'  'a'  'g' 'g'  'gsh' 
'dikla' 'aba'  'mama'  'a'  'h' 'ghfs' 'bfsbf' 
'4'  ''   ''   'nn' ''  ''  'hadhd' 
1

你似乎在過度工作。

cooked = regexprep(raw,'NaN',''); 

這樣做。


,當然還有,假設你沒有得到支付額外的$ 1000的每一行代碼,你不寫:

cooked = raw; 
for I = 1:length(raw(:)) 
    if strcmp(raw{I},'NaN') 
     cooked{I} = ''; 
    end 
end 
+1

你說得對'regexprep'是一個字符串數組(在本例中爲'raw'),它是一個有效的輸入,所以在這種情況下'cellfun'是完全不必要的。關於'for'循環,我發現使用正則表達式修改字符串(''regexprep'')可以更方便,更容易出錯。使用'if strcmp'代碼結構代替好的乾淨的'regexprep'似乎對我來說太複雜了,'regexprep'我可以在一行代碼中看到替換。 – nrz

+0

@nrz在matlab中編寫能自動完成多索引for循環的單行代碼是一件好事。但是由於目標是以低成本實現可用性,所以重要的是要記住,可以編寫而不必學習大量新特徵的for循環有時比單行矩陣 - 陣列 - 單元 - 結構對象代碼,可能需要數天才能弄清楚。 – mwengler

1

另一種解決方案:

%# replace all 'NaN' with '' 
raw(ismember(raw,'NaN')) = {''}; 

%# remove rows/columns of all empty strings 
raw(:,all(cellfun(@isempty,raw),1)) = []; 
raw(all(cellfun(@isempty,raw),2),:) = [];