Я использую Mathematica 7 для обработки большого набора данных. Набор данных представляет собой трехмерный массив целых чисел со знаком. Эти три уровня можно рассматривать как соответствующие X очков за выстрел , Y кадров за сканирование и Z сканирований на набор .
У меня также есть снимок «обнуления» (содержащий X точек, которые представляют собой целые числа со знаком ), который я хотел бы вычесть из каждого кадра в наборе данных. Впоследствии мне больше никогда не понадобится исходный набор данных.
Как я могу выполнить это преобразование, не создавая в процессе новые копии набора данных или его частей? Концептуально набор данных находится в памяти, и я хотел бы просканировать каждый элемент и изменить его в этом месте в памяти, без постоянного копирования в какое-то другое место в памяти.
Следующий автономный код фиксирует все аспекты того, что я пытаюсь сделать:
(* Create some offsetted data, and a zero data set. *)
myData = Table[Table[Table[RandomInteger[{1, 100}], {k, 500}], {j, 400}], {i, 200}];
myZero = Table[RandomInteger[{1, 9}]/RandomInteger[{1, 9}] + 50, {i, 500}];
(* Method 1 *)
myData = Table[
f1 = myData[[i]];
Table[
f2 = f1[[j]];
f2 - myZero, {j, 400}], {i, 200}];
(* Method 2 *)
Do[
Do[
myData[[i]][[j]] = myData[[i]][[j]] - myZero, {j, 400}], {i, 200}]
(* Method 3 *)
Attributes[Zeroing] = {HoldFirst};
Zeroing[x_] := Module[{},
Do[
Do[
x[[i]][[j]] = x[[i]][[j]] - myZero, {j, Length[x[[1]]]}
], {i, Length[x]}
]
];
(Примечание: подсказка Аарону Хонеккеру для метода №3.)
На моей машине (Процессор Intel Core2 Duo 3,17 ГГц, 4 ГБ ОЗУ, 32-разрядная версия Windows 7), все три метода используют примерно 1,25 ГБ памяти, при этом обтекатели №2 и №3 немного лучше.
Если я не против потери точности, обертывание N []
внутри myData
и myZero
при их создании увеличивает их размер. в памяти на 150 МБ изначально, но уменьшает объем памяти, необходимый для обнуления (с помощью методов №1- №3 выше) с 1.С 25 ГБ до 300 МБ! Это мое рабочее решение, но было бы здорово узнать, как лучше всего справиться с этой проблемой.