hig*_*ggy 6 wolfram-mathematica
我正在使用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]}
]
];
Run Code Online (Sandbox Code Playgroud)
(注意:帽子提示Aaron Honecker方法#3.)
在我的机器上(Intel Core2 Duo CPU 3.17 GHz,4 GB RAM,32位Windows 7),这三种方法都使用大约1.25 GB的内存,#2和#3整流罩稍好一些.
如果我不介意失去精度,缠绕N[ ]
周围的内脏myData
和myZero
正在被创建时,他们增加了他们通过150 MB内存最初的大小,但降低了内存归零所需的量(按方法#1以上#3) 1.25 GB低至300 MB!这是我的工作解决方案,但知道处理这个问题的最佳方法会很棒.
不幸的是我现在没有时间,所以我必须简明扼要......
处理大数据时,您需要注意Mathematica有一种称为压缩数组的不同存储格式,它比常规数据更紧凑,更快,但仅适用于机器实数或整数.
?Developer`*Packed*
如果没有自动发生,请评估以查看可直接转换为/从哪些函数可用的函数.
因此,为什么我的解决方案快速且内存有效的简要解释是它使用打包数组.我测试使用Developer`PackedArrayQ
我的数组永远不会解压缩,我使用机器实数(我应用于N[]
所有)
In[1]:= myData = N@RandomInteger[{1, 100}, {200, 400, 500}];
In[2]:= myZero =
Developer`ToPackedArray@
N@Table[RandomInteger[{1, 9}]/RandomInteger[{1, 9}] + 50, {i, 500}];
In[3]:= myData = Map[# - myZero &, myData, {2}]; // Timing
Out[3]= {1.516, Null}
Run Code Online (Sandbox Code Playgroud)
此外,您要求的操作("我想扫描每个元素,并在内存中的该位置更改它")称为映射(请参阅Map[]
或/@
).