Допустим, у меня есть два набора данных, каждый из которых состоит из массива x
и y
, например:
x_1 = [1 2 3 4 5 6 7 8 9 10];
y_1 = [8 12 20 3 4 9 10 55 3 2];
x_2 = [2 5 6 8 9];
y_2 = [4 18 3 12 1];
Теперь я хотел бы рассчитать новую метрику z = y_1 ./ y_2
, но я хочу сравнить элементы y_1
по элементам y_2
с тем же x
значением:
z = [12 4 9 55 3 2] ./ [4 18 3 12 1]
Как я могу затем эффективно найти этот второй массив, содержащий только значения y_2
с соответствующим значением x_2
, которое встречается в x_1
?
До сих пор я придумал это решение, но я сомневаюсь, что это самая эффективная возможность:
for i = 1:numel(x_2)
z(i) = y_2(i) / y_1(y_1 == x_2(i));
end
Поскольку в Matlab обычно можно избежать зацикливания элементов, я предполагаю, что есть лучшие способы сделать это.
Итак, в основном, я хочу передискретизировать второй набор данных, чтобы сделать его массив x_2
равным x_1
Вы могу векторизуете это, используя ismember
:
[Lia,Locb] = ismember(x_1, x_2);
z = y_1(Lia) ./ y_2(nonzeros(Locb).');
Будете ли вы должен или нет, это другой вопрос. Избегание циклов в MATLAB в значительной степени является устаревшей стратегией, так как MATLAB начал внедрять механизм JIT-компиляции. У меня есть сомнения, что векторизованная версия будет быстрее, чем цикл for, за исключением может быть для самых больших наборов данных, и я не верю, что она более читабельна. YMMV
Аналогично предыдущему ответу, но короче:
y_1(ismember(x_1,x_2))./y_2
Примечание. Я проверил это на Octave, так как у меня нет лицензии Matlab.
Это будет работать до тех пор, пока ismember(x_1,x_2)
и y_2
имеют одинаковую длину, то есть когда в x_2
нет элементов, которые не представлены в x_1
, и ни в одном из них нет дубликатов. Но если эти условия выполняются, это разумное решение.
Спасибо за ваше понимание использования циклов, не знал об этом. Я думаю, что тогда я буду придерживаться своего решения для удобочитаемости.