Как выполнить цикл по каждому значению в 3D-матрице?

#matlab

#matlab

Вопрос:

У меня есть матрица 10x10x40, которая хранит информацию об изображении во времени, где строки и столбцы указывают спектральное значение в определенной точке, а третье измерение — это время. Другими словами, изображение размером 10×10 в 40 точках времени. Я хотел бы выполнить цикл по каждой строке, столбцу и просмотреть историю этих пикселей (1,1,:), (1,2,:)….(10,10,:).

Вот что я сейчас делаю:

 val = [];
for i = 1:10;
  for j = 1:10;
    for k = 1:length(timevector)
      val(k) = my_matrix(i,j,k); 
    end
  end
end
  

Поскольку я хочу выполнить итерацию по каждому пикселю во времени, а затем сохранить эти данные, каков наилучший способ сохранения новых значений / временных векторов? Я хочу получить 100 векторов истории пикселей, прямо сейчас я заканчиваю одним, и это потому, что значение val записывается в цикле. Я знаю, что не рекомендуется создавать переменные внутри цикла, так какова же лучшая альтернатива? Должен ли я рассмотреть возможность сохранения выходных данных в виде структуры? Я смотрел на это, и я все слишком усложнил.

Комментарии:

1. Неясно, каков ваш ожидаемый результат. Вам нужен векторный вывод из 100 элементов? Как 2D «слой» размером 10×10 должен соответствовать одномерному массиву? Вы ожидаете, что в итоге получится 100 векторов, каждый размером 1×40, содержащих все временные данные? Чем это отличается от вашей исходной матрицы?

2. В конечном итоге я собираюсь отфильтровать каждый вектор, что я мог бы сделать в цикле для создания отфильтрованной матрицы — я просто не могу понять, как создать / выполнить цикл

3. Вы также можете фильтровать в векторизованной форме, в зависимости от функции фильтра. Например, filtfilt работает по первому измерению с более чем 1 элементом, поэтому, переставляя матрицу, фильтруя, а затем отменяя перестановку, вы получите огромный прирост производительности по сравнению с циклированием.

4. Это звучит как проблема X-Y . Укажите, чего вы пытаетесь достичь, а не только как решить крошечную часть проблемы. Наилучший формат вывода будет зависеть от того, что вы пытаетесь сделать, и, как говорит @rinkert, вам может вообще не понадобиться этот шаг

5. Пожалуйста, добавьте минимальный пример и желаемый результат.

Ответ №1:

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

Альтернатива 1:

 A = reshape(A,[],10);
  

Это вернет матрицу (100×40), где каждая строка представляет собой историю пикселей.

Альтернатива 2:

 A = num2cell( reshape(A,[],40), 2)
  

Это вернет массив ячеек (100×1), где каждая ячейка содержит вектор (40×1) с историей каждого пикселя.

Альтернатива 3:

 A = squeeze( num2cell( permute(A, [3,1,2]), 1) );
  

Это вернет массив ячеек (10×10), где каждая ячейка содержит вектор (40×1) с историей каждого пикселя.

Комментарии:

1. Добро пожаловать! Проверяя ваши другие вопросы, я увидел, что вы не приняли ни одного ответа. Если вы просто не были удовлетворены предоставленными ответами до сих пор, это совершенно нормально. Однако, если вы просто не заметили, как вы это делаете, вы можете принять ответ, нажав на галочку рядом с ним, и он больше не будет отображаться на доске как неотвеченный. ( Конечно, принимайте ответ, только если он работает и хорошо отвечает на ваш вопрос. )

Ответ №2:

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

 pixel_history = squeeze(my_matrix(1,1,:));
  

squeeze удалит одноэлементное измерение из среза и преобразует его в вектор размером 40 на 1 вместо матрицы размером 1 на 1 на 40.

Чтобы сделать измерение времени первым матричным измерением, вы также могли permute использовать матрицу,

 permute(my_matrix, [3 2 1]);
  

Это поменяет местами 3-е и 1-еизмерения, создав 1-е измерение времени.

Комментарии:

1. Спасибо за предложение. Итак, перебираем каждую точку матрицы, для i = 1: 10 для j = 1:10; pixel_history = squeeze(my_matrix(i,j,:)); end end ? Я все еще получаю только один вектор.