首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MemoryError在numpy.append中尽管有足够的内存

MemoryError在numpy.append中尽管有足够的内存
EN

Stack Overflow用户
提问于 2019-06-19 02:20:49
回答 1查看 621关注 0票数 4

我一直试图将用laspy读取的点云的点列表附加到另一个点列表中,基本上合并了两个点云。在合并多个点云时,我已经将所有点附加到同一个np.ndarray中,以便将其保存回一个laspy文件。现在,只要我想要合并的所有点云的合并大小超过350 MB,我就会得到一个MemoryError

我尝试过使用一种不同的方法来编写切入点云文件,这样我就不必一次将所有的点读入内存,但是失败了,因为laspy在编写点云文件时真的很奇怪,下面是我发现的几点:

  • laspy.File.points具有以下格式:
代码语言:javascript
复制
array([((24315,  12245, 12080, 0, 24, 0, 0, 0, 202, 23205, 24735, 21930),),
       ...,
       ((15155, -23292, -6913, 0, 56, 0, 0, 0, 343, 36975, 37230, 37485),)],
      dtype=[('point', [('X', '<i4'), ('Y', '<i4'), ('Z', '<i4'), ('intensity', '<u2'), ('flag_byte', 'u1'), ('raw_classification', 'u1'), ('scan_angle_rank', 'i1'), ('user_data', 'u1'), ('pt_src_id', '<u2'), ('red', '<u2'), ('green', '<u2'), ('blue', '<u2')])])
  • laspy.File.points的变量类型是numpy.ndarray
  • laspy.File.points的形状是(<numberOfRows>,) =>一维数组,尽管它每行有12个值(?)
  • 行的类型为numpy.void
  • 为了编写laspy.File,您需要在写入模式下创建一个新文件,从现有文件中复制头文件,并将File.points设置为与上述类型完全相同的numpy数组。在设置了一次点之后,您就不能再次设置它们,这意味着在设置点时需要知道行的最终计数。
  • 可以使用laspy.File.set_x(<arrayOfXValues>) (和类似的)更改行的值,需要与laspy.File.points相同的长度

现在我的PC有16 GB内存,当我开始合并时,其中大约10 GB是免费的。使用psutils,我得到了使用可用内存,并且我的空闲内存从未低于9 GB。使用psutil.Process(os.getpid()).memory_info().rss,我得到了这个进程的使用内存,这个内存从未超过650 MB。

合并时,我读取第一个文件,然后遍历其他文件,逐个读取它们,并调用numpy.append(combinedPoints, otherPointcloudPoints)将所有点叠加在一起。但是,当上面列出的条件为真时,这会抛出一个MemoryError

下面是将多个点云合并到一个新的点云的代码(所有这些都发生在类PointCloudFileIO中,self.filelaspy.File的一个实例)。util.inMB计算从字节到兆字节的大小。

代码语言:javascript
复制
    def mergePointClouds(self, listPaths, newPath):
        realSize = util.inMB(psutil.Process(os.getpid()).memory_info().rss)
        print("Process Memory used at start: {:.2f}MB".format(realSize))
        print("Available memory at start: {:.2f}MB".format(util.inMB(psutil.virtual_memory().available)))

        pointsOwn = self.file.points
        firstOtherReader = PointCloudFileIO(listPaths[0])
        pointsCombined = np.append(pointsOwn, firstOtherReader.file.points)

        realSize = util.inMB(psutil.Process(os.getpid()).memory_info().rss)
        print("Process Memory used after first merge: {:.2f}MB".format(realSize))
        print("Available memory after first merge: {:.2f}MB".format(util.inMB(psutil.virtual_memory().available)))

        for i in range(1, len(listPaths)):
            otherReader = PointCloudFileIO(listPaths[i])
            otherPoints = otherReader.file.points

            pointsCombined = np.append(pointsCombined, otherPoints)

            realSize = util.inMB(psutil.Process(os.getpid()).memory_info().rss)
            print("Process Memory used in loop: {:.2f}MB".format(realSize))
            print("Available memory in loop: {:.2f}MB | Used: {:.2f}MB | Percent: {}%".format(util.inMB(psutil.virtual_memory().available), util.inMB(psutil.virtual_memory().used), psutil.virtual_memory().percent))

        outFile = File(newPath, mode='w', header=self.file.header)
        outFile.points = pointsCombined
        outFile.close()

对于我所拥有的几乎所有用例来说,这都是非常好的。它将所有提供的点云合并到新文件中的新点云。然而,当产生的点云有点太大时,尽管内存比需要大得多,我还是会得到一个MemoryError

下面是我用这些点云(下载.laz文件)启动程序时的日志,您需要先用laszip解压缩.laz文件,然后才能使用laspy (至少在使用Windows时):

代码语言:javascript
复制
Process Memory used at start: 21.18MB
Available memory at start: 9793.35MB | Used: 6549.50MB | Percent: 40.1%
Process Memory used after first merge: 381.63MB
Available memory after first merge: 9497.64MB | Used: 6845.20MB | Percent: 41.9%
Process Memory used in loop: 559.52MB
Available memory in loop: 9309.36MB | Used: 7033.48MB | Percent: 43.0%
Process Memory used in loop: 637.05MB
Available memory in loop: 9301.00MB | Used: 7041.85MB | Percent: 43.1%
Traceback (most recent call last):
  File "optimization_test.py", line 7, in <module>
    f1.mergePointClouds(paths, "someShiet.las")
  File "C:\Users\viddie\Desktop\git\GeoLeo\geoleo\pointcloud.py", line 175, in mergePointClouds
    pointsCombined = np.append(pointsCombined, otherPoints)
  File "C:\Users\viddie\AppData\Local\Programs\Python\Python36-32\lib\site-packages\numpy\lib\function_base.py", line 5166, in append
    return concatenate((arr, values), axis=axis)
MemoryError

如果有人知道原因,任何帮助都是值得感谢的。

EN

回答 1

Stack Overflow用户

发布于 2019-06-19 02:47:16

如果操作实际上不适合内存,您可以将一些硬盘驱动器作为内存进行操作。

Windows操作系统

或者你可以在Ubuntu上使用交换空间。

也许从这一点开始,直到你能找到减少内存消耗的方法。或者至少这可以通过确保您确实有足够的内存来帮助您排除故障。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56659214

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档