matlab从基质中去除NaN

时间:2012-06-14 21:25:22

标签: matlab vectorization nan cell-array

我有一个矩阵:

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'

我想删除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.

我尝试过Ansari的解决方案,但现在我得到了:

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) 

并得到:

7

4 个答案:

答案 0 :(得分: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

对于最后一步,你可以循环以保持代码清洁和易懂(并且更容易调试!)。您基本上是通过连接字符串来折叠每一行或每列,然后检查长度是否为零,以及是否正在删除该行或列。

答案 1 :(得分: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)) = [];

因此,首先使用'NaN'raw''的所有cellfun字符串替换为repexprep,结果存储在output中}。然后,通过使用NaNrawraw'NaN'的每个字符串与cellfun进行比较,创建逻辑矩阵strcmp。最后,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'

答案 2 :(得分:1)

你似乎过度劳累了。

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

做到了。


当然,假设你没有为你不写的每行代码额外支付1000美元:

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

答案 3 :(得分: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),:) = [];