2012-06-14 367 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),:) = [];