#arrays #matlab #matrix #vectorization
#массивы #matlab #матрица #векторизация
Вопрос:
Мне нужен быстрый способ извлечения частей в матрице и складывания их в новую матрицу. Предположим, у меня была такая матрица:
M =
1 45 4
1 91 15
2 34 89
3 89 9
3 96 99
Теперь я хочу, например, получить все элементы в последних двух столбцах, т.е. левый столбец имеет значения [1; 3], т. Е. Вывод должен выглядеть следующим образом:
45 4
91 15
89 9
96 99
Чтобы получить, например, часть, соответствующую 1 в первом столбце, я мог бы сделать
M(M(:,1) == 1,2:end),
и я мог бы использовать логическое «или», чтобы получить части, соответствующие [1;3] , но в реальном случае у меня был бы длинный вектор целых чисел… есть ли векторизованный способ сделать это?
Я думаю, что цикл for тоже может быть довольно быстрым, но части матрицы будут разного размера, и их быстрое сложение может быть затруднено…
Комментарии:
1. проверьте
ismember()
функцию. Определите сами массив, содержащий соответствующие вам значения (например, [1,3] ). Затем проверьте, является ли элемент в M членом этого вектора.2. Спасибо за подсказку, Миньон, это действительно работает! Также опубликую свой собственный ответ ниже…
3. Обычно со сколькими целыми числами вы бы сравнивали? Если это всего лишь два типа
[1 3]
, использованиеM(:,1) == 1 | M(:,1) == 3
может быть быстрее, чемbsxfun
решение, я думаю, может быть, не очень удобное.4. Divakar: много целых чисел…
5. Если какое-либо решение, размещенное здесь, удовлетворяет потребностям вопроса, подумайте о том, чтобы принять его, чтобы
SO
можно было рассматривать это как «закрытый случай», и людям с аналогичными потребностями помогают самым правильным образом.
Ответ №1:
Посмотрите, достаточно ли это быстро для вас —
int_arr = [1 3]; %// array of integers to select the rows
M(any(bsxfun(@eq,M(:,1),int_arr),2),2:end)
Или
int_arr = [1;3]; %// array of integers to select the rows
M(any(bsxfun(@eq,M(:,1)',int_arr)),2:end)
Комментарии:
1. Какая польза
any
в этом случае? Как вы выбираете строки? Насколько я вижу, выводany
используется для выбора строкM
в этом экземпляре, и any() вернет 0 или 1 итак, как вы получаете правильные строки? При этом выбирается номер строки 0 или 1, если я правильно понял код.2. @kkuilla
bsxfun
вывод с@eq
представляет собой двоичную матрицу сones
в местах, где выполняется условие равенства между первым столбцом M1
и3
. Использованиеany
здесь похожеOR
на выбор строк, соответствующих тому, когда столбец 1 имеет1
ИЛИ3
. Надеюсь, это будет иметь смысл! 🙂3. Я не согласен с тем фактом, что
any()
возвращает номера строк, но привет… ваш ответ работает. 🙂 14. @kkuilla Он не возвращает номер строки, он возвращает логический массив «допустимых строк» после «ORing» with
any
. Этот логический массив используется для индексации в эти допустимые строки, таким образом, используяlogical indexing
. Использованиеany
здесь простоORing
, вот и все.5. @kkuilla Точно! Если вы запустите его по частям, надеюсь, все будет ясно! 🙂 Спасибо за голосование! 😉
Ответ №2:
Найден ответ, основанный на предложении Миньона… итак, сначала найдите строки, которые удовлетворяют условию:
idx = ismember(testmat(:,1),[1 3])
ans =
1
1
0
1
1
Теперь замените первый столбец:
M(:,1) = idx
M=
1 45 4
1 91 15
0 34 89
1 89 9
1 96 99
… а затем просто сделайте
M(M(:,1)==1,2:end).
Я не сравнивал скорость с решением Дивакара выше, так как я спешу, но давайте посмотрим, какой из них быстрее! 😉
Комментарии:
1. Не могли бы вы добавить ссылку на сообщение, на котором вы основали это, пожалуйста?
2. Или, действительно, просто используйте
m(ismember(m(:,1),[1,3]),2:end)
3. @MikeLimaOscar вот к чему я пытался добраться. Просто я бы рекомендовал перейти
[1 3]
на массив, который вы определяете где-то в другом месте. Тогда легче модифицировать.4. 1, хотя решение с
bsxfun
может быть быстрее5. Просто любопытно, смогли ли вы получить некоторые тесты времени выполнения для представленных решений.