(Юлия) Быстро сделайте сумму по столбцам по массиву - PullRequest
2 голосов
/ 02 ноября 2019

У меня есть массив MxN A с плавающей точкой, и я хотел бы выполнить следующую операцию: Для каждого столбца A подсчитать количество элементов, которые меньше некоторого порогового значения (например, 0,5).

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

function count(A)
    (cols, rows) = size(A)
    result = fill(0, cols)
    for j in 1:rows
        for i in 1:cols
            result[i] += A[i,j] <= 0.5
        end
    end
end

. Он проходит A в том же порядке, что и расположение в памяти, и не выделяет лишнего дополнительного пространства. Однако я не уверен, как это сделать, используя, например, операторы вещания. <= 0,5, сумма и т. Д. Один из способов сделать это - </p>

sum(A .<= 0.5, dims=1)

, но это выделяет новую память только для выполнения операций ипримерно в 2-3 раза медленнее, чем функция подсчета (я проверял это для массивов до 8000x8000). Можно ли добиться производительности функции подсчета, используя всего несколько строк кода (как во втором методе)?

1 Ответ

4 голосов
/ 02 ноября 2019

Естественный способ написать ваше условие:

count.(<=(0.5), eachcol(A))

или

vec(sum(<=(0.5), A, dims=1))

(последний немного медленнее первого, но выполняет гораздо меньше ассигнований, поэтомувероятно, баланс производительности будет зависеть от размеров матрицы)

В общем, оба должны быть достаточно быстрыми и легко читаемыми.

Примечание: ваш код выполняет подсчет в строках, не находящихся вколонны. Это способ исправить это для выполнения подсчета в столбцах:

function count2(A)
    (rows, cols) = size(A)
    result = fill(0, cols)
    for i in 1:cols
        for j in 1:rows
            result[i] += A[j,i] <= 0.5
        end
    end
    result
end

Наконец, обратите внимание, что sum(A .<= 0.5, dims=1) выполняет немного иную операцию, так как возвращает Matrix, а не Vector.

...