3

我有一组点(x 和 y),我想知道 X 和 Y(边界框)的最大值和最小值。我对这些行进行了编码,在这些行中我使用列表理解读取了所有点,然后在 X 和 Y 上使用了 max 和 min。最后我删除了这些点。

这个解决方案不是内存效率,因为我需要读取所有点

points = [(p.x,p.y) for p in lasfile.File(inFile,None,'r')] # read in list comprehension
X_Max = max(zip(*points)[0])
X_Min = min(zip(*points)[0])
Y_Max = max(zip(*points)[1])
Y_Min = min(zip(*points)[1])
del points

我要求建议避免此步骤(将所有点存储在内存中)。提前感谢詹尼

4

2 回答 2

5
X_Max = float('-inf')
X_Min = float('+inf')
Y_Max = float('-inf')
Y_Min = float('+inf')

for p in lasfile.File(inFile,None,'r'):
    X_Max = max(X_Max, p.x)
    X_Min = min(X_Min, p.x)
    Y_Max = max(Y_Max, p.y)
    Y_Min = min(Y_Min, p.y)

这样,您只需在文件上循环一次,并避免一次在内存中拥有多个点。

EDIT File()提供了一个迭代器,它一次只从文件中读取一行,p并在需要时将其提供给循环变量。

在您的问题中,您在初始点分配周围使用了方括号。这是一个列表推导,顾名思义,它创建了一个列表——所以从那时起所有的点都保存在内存中。如果您像这样使用括号:

points = ((p.x,p.y) for p in lasfile.File(inFile,None,'r'))

X_Max = float('-inf')
X_Min = float('+inf')
Y_Max = float('-inf')
Y_Min = float('+inf')

for p in points:
    X_Max = max(X_Max, p.x)
    X_Min = min(X_Min, p.x)
    Y_Max = max(Y_Max, p.y)
    Y_Min = min(Y_Min, p.y)

...然后 Python 不会创建一个列表,而是一个生成器/迭代器——它会一次返回一个点,直到文件用完。这将避免同时在内存中拥有所有点 - 但只能迭代一次。

不过,为了简单起见,我放弃了创建一个额外的迭代器,而是lasfile.File()直接使用它。

于 2012-10-18T11:11:58.787 回答
3

您可以使用生成器表达式 forpoints并使用key参数 for maxand min

from itertools import tee
points = ((p.x,p.y) for p in lasfile.File(inFile,None,'r'))
points = tee(points, 4)

X_Max = max(points[0], key=lambda x:x[0])[0]
X_Min = min(points[1], key=lambda x:x[0])[0]
Y_Max = max(points[2], key=lambda x:x[1])[1]
Y_Min = min(points[3], key=lambda x:x[1])[1]

更新:

我添加了对itertools.tee的调用以复制原始生成器。

如评论中所述,此解决方案的缺点是您必须(不必要地)对文件进行 4 次迭代。正如@SteveMayne所做的那样,计算每次迭代的最大值和最小值,可以避免这种情况。

于 2012-10-18T11:10:03.730 回答