2015-06-17 2 views
0

Я создал эту переменную в рабочем пространстве:Заменить часть массива со средним своих соседей

z= 

0.000894000000000000 

-0.000929000000000000 

0.00101500000000000 

0.000747000000000000 

0.00103900000000000 

0.000888000000000000 

0.000828000000000000 

0.000737000000000000 

0.000858000000000000 

-0.000723000000000000 

0.000874000000000000 

Я хотел бы написать код, который будет заменить отрицательные со средним чисел найдены непосредственно над и ниже этого числа.

+3

Как вы справляетесь случай, когда имеется несколько негативов в последовательной последовательности? – rayryeng

+3

Также, что произойдет, если первый элемент и/или последний элемент отрицательны? – rayryeng

+0

Так в чем же дело? Кто-нибудь из нас ответил на ваш вопрос? – rayryeng

ответ

0

Попробуйте это:

for index = 1 : length(z) 
    if (z(index) < 0) // FIXED 
     above = max(index, 1); 
     below = min(index, length(z)); 
     z(index) = mean(z(above), z(below)); // FIXED 
    end 
end 

, но это не совсем верно. Что должно произойти в следующих случаях:

  • Как и в вопросе @ Ĭnfernal Seraphím, когда соседи также отрицательны.
  • Если есть первый и последний пункты негатива?
+0

Я обманул его. Я исправлю это. –

+0

Еще один комментарий. 'above' и' below' на самом деле ничего не делают. Это в основном просто «индекс». Вы имели в виду 'above', чтобы быть' above = max (index - 1, 1); 'и' below' to 'ниже = min (index + 1, length (z));' ?? – rayryeng

3

Вы можете приблизиться к этому в линейной интерполяционной точке. Если предположить, что нет последовательных отрицательных чисел в z, вы можете сделать это с interp1:

%// Define your data 
z= [... 
0.000894000000000000 
-0.000929000000000000 
0.00101500000000000 
0.000747000000000000 
0.00103900000000000 
0.000888000000000000 
0.000828000000000000 
0.000737000000000000 
0.000858000000000000 
-0.000723000000000000 
0.000874000000000000]; 

keys = (1 : numel(z)).'; 
out = interp1(keys(z >= 0), z(z >= 0), keys, 'linear', 'extrap'); 

Это также обрабатывает случай, где есть отрицательные значения в начале и в конце, а extrap флаг просто экстраполирует. Я не уверен, что это то, что вы намеревались, если есть значения в начале и конце, которые являются отрицательными, но я оставлю это для вас, чтобы понять.

Тем не менее, красота этого подхода заключается в том, что мы предоставляем контрольные точки, которые очерчены от 1 до нескольких точек в z, которые у нас есть. Это x баллов. Выходные данные y указывают значения в z. Однако мы удаляем те контрольные точки, которые являются отрицательными - то же самое делается для z.

Далее мы определяем полный спектр ключевых точек от 1 до количества элементов в z для достижения конечного результата. Использование линейной интерполяции в этом случае эффективно находит среднее значение между двумя точками, разделенными отрицательным.

Однако, если есть последовательные отрицательные числа, тогда произойдет то, что мы рассмотрим значение, которое было положительным до начала цепи отрицательных значений, и посмотрим на значение, положительное после цепочки, и в между прогонными последовательными числами значения плавно интерполируются. Я не уверен, что это то, что ты хочешь, поэтому я оставлю это для тебя, чтобы понять.

Это на выходе мы получаем:

>> format long g; 
>> out 

out = 

       0.000894 
      0.0009545 
       0.001015 
       0.000747 
       0.001039 
       0.000888 
       0.000828 
       0.000737 
       0.000858 
       0.000866 
       0.000874 

В качестве альтернативы, вы можете использовать find, но при следующих предположениях:

Этот код работает со следующими предположениями:

  1. z не имеет отрицательного числа в начале и в конце
  2. В z нет последовательных отрицательных чисел.

Поэтому:

%// Find negative values in z 
ind = find(z < 0); 

%// Replace each negative value with the 
%// average of the values above and below each negative 
z(ind) = (z(ind-1) + z(ind+1))/2; 

Приведенный выше код мутирует z так, что отрицательные значения заменяются соседней средней. Мы снова получаем:

>> format long g; 
>> z 

z = 

       0.000894 
      0.0009545 
       0.001015 
       0.000747 
       0.001039 
       0.000888 
       0.000828 
       0.000737 
       0.000858 
       0.000866 
       0.000874 
+1

Должно быть 'keys (z> = 0)', правильно? –

+0

Также можно указать аргумент экстраполяции, чтобы учесть случай, когда конечные элементы отрицательные (здесь я предлагаю «ближайший» алгоритм экстраполяции) –

+1

Вероятно, лучший подход! –

4

не самый эффективный подход, но ...

av = conv(z, [.5 0 .5], 'same'); %// compute average for all elements 
ind = z<0;      %// determine which are negative 
z(ind) = av(ind);     %// replace those only 
+0

Тем не менее, действительный подход: – rayryeng