может быть
(*data*)
nRow = 5; nCol = 5;
With[{$nRow = nRow, $nCol = nCol},
xnow = Table[RandomReal[{1, 3}], {$nRow}, {$nCol}];
cellactvA = cellactvB = cellactvC = Table[Random[], {$nRow}, {$nCol}]
];
limit = 2.0;
теперь сделайте замену
pos = Position[xnow, x_ /; x > limit];
{cellactvA, cellactvB, cellactvC} =
Map[ReplacePart[#, pos -> 0.] &, {cellactvA, cellactvB, cellactvC}];
редактировать (1)
Вот быстрая скорость, сравнивающая 4 метода выше, LOOP, а затем Бретта, меня и Вербейю. Может быть, кто-то может перепроверить их. Я использовал одни и те же данные для всех. создал случайные данные один раз, а затем использовал их для каждого теста. Тот же предел (называемый L) Я использовал размер матрицы 2000 на 2000.
Значения приведенных ниже скоростных временных параметров не включают распределение данных.
Я запускаю тесты один раз.
Вот что я вижу:
Для матриц 2000 на 2000:
- Счет (цикл): 16 секунд
- я (
ReplacPart
): 21 секунда
- Бретт (
SparseArray
): 7,27 секунды
- Вербея (
MapThread
): 32 секунды
Для 3000 на 3000 матриц:
- Счет (цикл): 37 секунд
- я (
ReplacPart
): 48 секунд
- Бретт (
SparseArray
): 16 секунд
- Вербея (
MapThread
): 79 секунд
Итак, похоже, что SparseArray
самый быстрый. (но, пожалуйста, проверьте, чтобы я ничего не сломал)
код ниже:
генерация данных
(*data*)
nRow = 2000;
nCol = 2000;
With[{$nRow = nRow, $nCol = nCol},
$xnow = Table[RandomReal[{1, 3}], {$nRow}, {$nCol}];
$a = $b = $c = Table[Random[], {$nRow}, {$nCol}]
];
limit = 2.0;
ReplacePart test
xnow = $xnow;
a = $a;
b = $b;
c = $c;
Timing[
pos = Position[xnow, x_ /; x > limit];
{xnow, a, b, c} = Map[ReplacePart[#, pos -> 0.] &, {xnow, a, b, c}]][[1]]
Тест SparseArray
xnow = $xnow;
a = $a;
b = $b;
c = $c;
Timing[
matrixMask =
SparseArray[Thread[Position[xnow, _?(# > limit &)] -> 0.],
Dimensions[xnow], 1.]; xnow = xnow*matrixMask;
a = a*matrixMask;
b = b*matrixMask;
c = c*matrixMask
][[1]]
Тест MapThread
xnow = $xnow;
a = $a;
b = $b;
c = $c;
Timing[
{xnow, a, b, c} =
MapThread[Function[{x, y}, If[x > limit, 0, y]], {xnow, #},
2] & /@ {xnow, a, b, c}
][[1]]
проверка петли
xnow = $xnow;
a = $a;
b = $b;
c = $c;
Timing[
Do[If[xnow[[i, j]] > limit,
xnow[[i, j]] = 0.;
a[[i, j]] = 0.;
b[[i, j]] = 0.;
c[[i, j]] = 0.
],
{i, 1, nRow}, {j, 1, nCol}
]
][[1]]
редактировать (2)
Что-то действительно беспокоит меня всем этим. Я не понимаю, как цикл может быть быстрее, чем специализированные команды для этой цели?
Я написал простой циклический тест в Matlab, как Билл использовал R, и я также получил гораздо меньшие значения времени. Я надеюсь, что эксперт может придумать гораздо более быстрый метод, потому что теперь я не слишком доволен этим.
Для матрицы 3000 на 3000 я получаю
Elapsed time is 0.607026 seconds.
Это более чем в 20 раз быстрее, чем метод SparseArray, и это просто цикл!
%test, on same machine, 4GB ram, timing uses cpu timing using tic/toc
%allocate data
nRow = 3000;
nCol = 3000;
%generate a random matrix of real values
%between 1 and 3
xnow = 1 + (3-1).*rand(nRow,nRow);
%allocate the other 3 matrices
a=zeros(nRow,nCol);
b=a;
c=b;
%set limit
limit=2;
%engine
tstart=tic;
for i=1:nRow
for j=1:nCol
if xnow(i,j) > limit
xnow(i,j) = 0;
a(i,j) = 0;
b(i,j) = 0;
c(i,j) = 0;
end
end
end
toc(tstart)
fyi: использование cputime () дает аналогичные значения. Как tic / toc.