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)

このようにして、ファイルを1回だけループするだけでなく、一度に複数のポイントがメモリに存在することを回避できます。

EDIT File()はイテレータを提供しています。イテレータは、ファイルから一度に1行だけを読み取り、必要に応じてループ変数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はリストを作成しませんが、ジェネレーター/イテレーター-ファイルが使い果たされるまで一度に1ポイントを返します。これにより、メモリ内のすべてのポイントが同時に存在することを回避できますが、繰り返すことができるのは1回だけです。

ただし、簡単にするために、追加のイテレーターの作成を中止し、イテレーターをlasfile.File()直接使用することにしました。

于 2012-10-18T11:11:58.787 に答える
3

にジェネレータ式をpoints使用し、およびに引数keyを使用できます。maxmin

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 に答える