7

これは前の質問です Python で関数の時間パフォーマンスを向上させるには、テキスト ファイルを分割する効率的な方法を見つける必要があります

次のテキスト ファイル (32 GB 以上)がソートされていません

....................
0 274 593869.99 6734999.96 121.83 1,
0 273 593869.51 6734999.92 121.57 1,
0 273 593869.15 6734999.89 121.57 1,
0 273 593868.79 6734999.86 121.65 1,
0 272 593868.44 6734999.84 121.65 1,
0 273 593869.00 6734999.94 124.21 1,
0 273 593868.68 6734999.92 124.32 1,
0 274 593868.39 6734999.90 124.44 1,
0 275 593866.94 6734999.71 121.37 1,
0 273 593868.73 6734999.99 127.28 1,
.............................

最初と 2 番目の列は、グリッド内の x、y、z ポイントの位置の ID (例: 0 -273) です。

def point_grid_id(x,y,minx,maxy,distx,disty):
    """give id (row,col)"""
    col = int((x - minx)/distx)
    row = int((maxy - y)/disty)
    return (row, col)

これ(minx, maxx)は、 size のグリッドの原点ですdistx,disty。Id タイルの数は

tiles_id = [j for j in np.ndindex(ny, nx)] #ny = number of row, nx= number of columns 
from [(0,0),(0,1),(0,2),...,(ny-1,nx-1)]
n = len(tiles_id)

~32 GB のファイルをn (= len(tiles_id))多数のファイルにスライスする必要があります。

ソートせずにこれを実行できますが、ファイルを n 回読み取ります。このため、 form を開始するファイルの効率的な分割方法を見つけたいと考えています(0,0) (= tiles_id[0])。その後、分割されたファイルを一度だけ読み取ることができます。

4

2 に答える 2

5

Pythonまたはコマンドラインツール()を使用しているかどうかに関係なく、32GBファイルの並べ替えはほとんど不可能ですsort。データベースは強力すぎるように見えますが、使用される可能性があります。ただし、データベースを使用したくない場合は、タイルIDを使用してソースファイルをファイルに分割することをお勧めします。

行を読み取り、タイルIDからファイル名を作成し、その行をファイルに追加します。そして、ソースファイルが完成するまでそれを続けます。速すぎることはありませんが、少なくともソートとは異なり、O(N)の複雑さがあります。

そしてもちろん、ファイルを個別に並べ替えて連結することも可能です。32GBファイルをソートする際の主なボトルネックは、CPUではなくメモリである必要があります。

これが、私が思う:

def temp_file_name(l):
    id0, id1 = l.split()[:2]
    return "tile_%s_%s.tmp" % (id0, id1)

def split_file(name):
    ofiles = {}
    try:
        with open(name) as f:
            for l in f:
                if l:
                    fn = temp_file_name(l)
                    if fn not in ofiles:
                        ofiles[fn] = open(fn, 'w')
                    ofiles[fn].write(l)
    finally:
        for of in ofiles.itervalues():
            of.close()

split_file('srcdata1.txt')

ただし、開くことができるファイルの数よりも多くのタイルがある場合は、次のようにすることができます。

def split_file(name):
    with open(name) as f:
        for l in f:
            if l:
                fn = temp_file_name(l)
                with open(fn, 'a') as of:
                    of.write(l)

そして、最も完璧な方法は、開いているファイルの数の制限に達した後、いくつかのファイルを閉じて辞書から削除することです。

于 2013-03-05T15:18:14.117 に答える
1

簡単なグーグルで、ActiveStateコードのこのレシピにたどり着きました。パフォーマンスの比較はありませんでしたが、仕事をしているようです。

要するに、@Ellioh が提案したことを実行しているようで、既製のレシピがあり、車輪を再発明する必要はないかもしれません。

于 2013-03-05T15:23:50.967 に答える