1

liblas モジュールを使用して *.las ファイルから一度に多数の行を読み取るために、「from itertools import islice」を使用しようとしています。(私の目標はチャンクバイチャンクを読むことです)

次の質問: Python で一度に N 行を読み取る方法

islice() を使用して、イテレータの次の n 個の項目を取得できます。したがって、list(islice(f, n)) は、ファイル f の次の n 行のリストを返します。これをループ内で使用すると、ファイルが n 行のチャンクで提供されます。ファイルの最後では、リストが短くなる可能性があり、最終的に呼び出しは空のリストを返します。

次のコードを使用しました。

from numpy import nonzero
from liblas import file as lasfile
from itertools import islice


chunkSize = 1000000

f = lasfile.File(inFile,None,'r') # open LAS
while True:
    chunk = list(islice(f,chunkSize))
    if not chunk:
        break
    # do other stuff

しかし、私はこの問題を抱えています:

len(f)
2866390

chunk = list(islice(f, 1000000))
len(chunk)
**1000000**
chunk = list(islice(f, 1000000))
len(chunk)
**1000000**
chunk = list(islice(f, 1000000))
len(chunk)
**866390**
chunk = list(islice(f, 1000000))
len(chunk)
**1000000**

ファイル f が最後に到着すると、 islice は再起動してファイルを読み取ります。

提案と助けをありがとう。とてもありがたいです

4

2 に答える 2

2

一度に n 行を出力するジェネレータを書くのは簡単に思えます:

def n_line_iterator(fobj,n):
    if n < 1:
       raise ValueError("Must supply a positive number of lines to read")

    out = []
    num = 0
    for line in fobj:
       if num == n:
          yield out  #yield 1 chunk
          num = 0
          out = []
       out.append(line)
       num += 1
    yield out  #need to yield the rest of the lines 
于 2012-10-08T14:17:07.737 に答える
2

file.pyliblas パッケージに属するのソースコードを変更します。現在は ( github の src )__iter__として定義されています。

def __iter__(self):
    """Iterator support (read mode only)

      >>> points = []
      >>> for i in f:
      ...   points.append(i)
      ...   print i # doctest: +ELLIPSIS
      <liblas.point.Point object at ...>
    """
    if self.mode == 0:
        self.at_end = False
        p = core.las.LASReader_GetNextPoint(self.handle)
        while p and not self.at_end:
            yield point.Point(handle=p, copy=True)
            p = core.las.LASReader_GetNextPoint(self.handle)
            if not p:
                self.at_end = True
        else:
            self.close()
            self.open()

ファイルが最後になると、ファイルが閉じられて再び開かれることがわかります。そのため、反復はファイルの先頭から再び開始されます。

しばらくしてから最後のelseブロックを削除してみてください。そのため、メソッドの正しいコードは次のようになります。

def __iter__(self):
    """Iterator support (read mode only)

      >>> points = []
      >>> for i in f:
      ...   points.append(i)
      ...   print i # doctest: +ELLIPSIS
      <liblas.point.Point object at ...>
    """
    if self.mode == 0:
        self.at_end = False
        p = core.las.LASReader_GetNextPoint(self.handle)
        while p and not self.at_end:
            yield point.Point(handle=p, copy=True)
            p = core.las.LASReader_GetNextPoint(self.handle)
            if not p:
                self.at_end = True
于 2012-10-08T14:31:24.897 に答える