2017-02-15 5 views
1

Если у меня есть двухколоночная матрица A, как показано ниже, я могу построить график рассеяния с использованием команды разброса/графика. Я хотел бы получить матрицу, соответствующую таким выводам, как в команде hist. Команда hist также дает векторный вывод.Как получить логическую матрицу, соответствующую «разбросанному» сюжету?

A=[7 1;3 2; 4 3] 

Например из = рассеяния (A (:, 1), A (:, 2)) должны дать что-то, как показано ниже:

[0 0 0; 
0 0 0; 
0 1 0; 
0 0 1; 
0 0 0; 
0 0 0; 
1 0 0] 

только индексы (7,1), (3,2) и (4,3) - только единицы. Или может кто-нибудь дать мне код фрагмента, чтобы реализовать это без использования циклов?

ответ

3

Вы можете использовать комбинацию sparse и full, где можно указать строки и столбца местоположения ненулевые, а остальные матрицы будет равен нулю:

A = [7 1; 3 2; 4 3]; 
B = full(sparse(A(:,1), A(:,2), 1, max(A(:,1)), max(A(:,2)))) == 1; 

Команда sparse занимает в строке и расположение столбцов того, что отличное от нуля для первых двух входов, третий вход - это то, что ненулевое местоположение будет для каждой строки и столбца. Мы можем указать константу для обозначения того, что каждое ненулевое местоположение получает тот же коэффициент, который равен 1. Мы также можем указать размер матрицы, где в этом случае строки и столбцы вывода соответствуют наибольшему числу в первый и второй столбцы соответственно. Поскольку это матрица sparse, вам необходимо преобразовать ее в матрицу full, и поскольку вы хотите, чтобы она была логической, вам нужно будет сравнить все элементы с номером 1.

Таким образом, мы получаем для вывода, который является B:

B = 

    7×3 logical array 

    0 0 0 
    0 0 0 
    0 1 0 
    0 0 1 
    0 0 0 
    0 0 0 
    1 0 0 

в качестве альтернативы можно использовать sub2ind для создания линейных индексов для индекса в предварительно выделенной матрицу logical ложных и установить только те ненулевые места строки в true:

A = [7 1; 3 2; 4 3]; 
B = false(max(A(:,1)), max(A(:,2))); 
ind = sub2ind(size(B), A(:,1), A(:,2)); 
B(ind) = true; 

Сначала мы выделим матрицу, а затем вычислим линейные индексы для индексации в матрицу, а затем, наконец, установим правильные местоположения на true. Результат здесь будет таким же, как и для подхода sparse.

+0

Ницца! Я также нашел, что 'accumarray (A, 1)' дает тот же результат. – dexterdev

+1

@dexterdev На самом деле это очень приятное решение.Извините, я не думал об этом. – rayryeng

+0

, честно говоря, я случайно наткнулся на эту команду на странице справки matlab. – dexterdev

3

Просто добавьте: решение Rayryeng прекрасно, если вы действительно хотите, чтобы ваш результат был логичным в том смысле, что он равен единице, если в координате есть что-то, а в противном случае - ноль. Тем не менее, поскольку вы добавили заметку об истории, мне было интересно, хотите ли вы на самом деле подсчитать количество ударов определенной координаты. В этом случае рассмотрите возможность использования

S = histcounts2(A(:,2),A(:,1)); 

если у вас есть доступ к R2015b +. Если нет, есть функция hist2 на файлообмене, которое вы можете использовать для этой цели.

3

Это мое решение. Matlab предоставляет команду под названием accumarray.

S = logical(accumarray(A, 1)) 

также даст результат.

+1

Вы можете немного закодировать гольф, выполнив 'S = accumarray (A, 1) == 1;' или 'S = ~~ accumarray (A, 1);' :). – rayryeng

+1

Мне это нравится, это также позволяет делать гистограммный подсчет, если это необходимо. – Florian