2012-06-14 4 views
1

У меня есть матрица:удалить MATLAB NaN из матрицы

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. 

Я попытался решение Ансари, но теперь я получил:

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)) = []; 

Таким образом, первый все 'NaN' строки raw заменяются '' по используя cellfun и repexprep, результат сохраняется в output. Затем логическая матрица NaNraw создается путем сравнения каждой строки raw с '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' 
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' в MATLAB). Использование кодовой структуры 'if strcmp' вместо чистого и чистого' regexprep' кажется мне слишком сложным, с 'regexprep' я вижу замену в одной строке кода. – nrz

+0

@nrz Возможность писать одиночные строки, которые автоматически выполняют мультииндекс для циклов, - это хорошая вещь в Matlab. Но поскольку цель - удобство использования при низкой стоимости, важно помнить, что цикл for, который может быть написан без необходимости изучать кучу новых функций, иногда превосходит n-ю абстракцию однострочной матрицы-матрицы-ячейки- код структуры-объекта, который может занять несколько дней. – 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),:) = []; 
Смежные вопросы