Scipy径向基函数中的Python MemoryError(scipy.interpolate.rbf)

hel*_*ker 7 python memory interpolation numpy scipy

我正在尝试使用Scipy径向基函数(Rbf)插值表示2D表面的不太大(~10,000个样本)的pointcloud.我得到了一些好的结果,但是我的上一个数据集我一直都在得到MemoryError,即使错误在执行期间几乎立即出现(RAM显然没有被吃掉).

我决定rbf.py从Scipy中删除该文件的副本,首先填写一些非常有用的打印语句.通过_euclidean_norm逐行分解方法,如下所示:

def _euclidean_norm(self, x1, x2):
    d = x1 - x2
    s = d**2
    su = s.sum(axis=0)
    sq = sqrt(su)
    return sq
Run Code Online (Sandbox Code Playgroud)

我在第一行收到错误:

File "C:\MyRBF.py", line 68, in _euclidean_norm
    d = x1 - x2
MemoryError
Run Code Online (Sandbox Code Playgroud)

该规范被称为数组X1,形式为[[x1,y1],[x2,y2],[x3,y3],...,[xn,yn]]和X2,它们是X1转换的在Rbf类内部的下面的方法,已经被我用于调试目的:

def _call_norm(self, x1, x2):
    print x1.shape
    print x2.shape
    print

    if len(x1.shape) == 1:
        x1 = x1[newaxis, :]
    if len(x2.shape) == 1:
        x2 = x2[newaxis, :]
    x1 = x1[..., :, newaxis]
    x2 = x2[..., newaxis, :]

    print x1.shape
    print x2.shape
    print

    return self._euclidean_norm(x1, x2)
Run Code Online (Sandbox Code Playgroud)

请注意我打印输入的形状.使用我当前的数据集,这就是我得到的(我手动添加了注释):

(2, 10744)         ## Input array of 10744 x,y pairs
(2, 10744)         ## The same array, which is to be "reshaped/transposed"

(2, 10744, 1)      ## The first "reshaped/transposed" form of the array
(2, 1, 10744)      ## The second "reshaped/transposed" form of the array
Run Code Online (Sandbox Code Playgroud)

根据文档,理由是得到"从x1中的每个点到x2中的每个点的距离的矩阵",这意味着,因为阵列是相同的,所以每对入口阵列之间的距离矩阵(其中包含X和Y维度).

我用更小的阵列(例如形状(2,5,1)和(2,1,5))手动测试操作,减法工作.

如何找出不使用我的数据集的原因?还有其他明显错误吗?我应该检查我的数据集的某种形式的病态调节,还是对它进行一些预处理?我认为它是条件良好的,因为我可以用3D绘制它,并且cloudpoint在视觉上非常好.

任何帮助将非常感谢.

谢谢阅读.

jor*_*eca 8

您的数据集应该没问题:出现错误是因为您没有足够的RAM来存储减法的结果.

根据广播规则,结果将有形

 (2, 10744,     1)
-(2,     1, 10744)
------------------
 (2, 10744, 10744)
Run Code Online (Sandbox Code Playgroud)

假设这些是dtype float64的数组,则需要2*10744**2*8 = 1.72 GiB的可用内存.如果没有足够的可用内存,numpy将无法分配输出数组,并且会立即失败并显示您看到的错误.

  • 1)如果大小是三分之一,所需内存减少9倍(因为内存与数据集大小的平方成比例)2)也许你可以在`su = s.sum(...)之前做`del d` ,或在一行中进行所有计算以避免中间结果.3)如果你的数据不适合RAM,我认为你仍然可以使用`np.memap`或PyTables,但我不熟悉它们. (2认同)