これは、上記の私のコメントに基づく提案です。圧縮された行がまだメモリに収まることに依存しています。そうでない場合は、他のソリューションが必要になります。
import zlib
from random import shuffle
def heavy_shuffle(filename_in, filename_out):
with open(filename_in, 'r') as f:
zlines = [zlib.compress(line, 9) for line in f]
shuffle(zlines)
with open(filename_out, 'w') as f:
for zline in zlines:
f.write(zlib.decompress(zline) + '\n')
私の経験では、zlib は高速ですが、bz2 の方が圧縮率が高いため、比較することをお勧めします。
また、たとえば n 行をまとめてチャンク化することができれば、そうすることで圧縮率が上がる可能性があります。
有用な圧縮の可能性について疑問に思っていたので、ここに IPython の実験があります。あなたのデータがどのように見えるかわからないので、フロート (文字列として) を 3 桁に丸め、パイプでつなぎました:
最良のシナリオ (たとえば、多くの行がすべて同じ数字を持つ):
In [38]: data = '0.000|'*200
In [39]: len(data)
Out[39]: 1200
In [40]: zdata = zlib.compress(data, 9)
In [41]: print 'zlib compression ratio: ',1.-1.*len(zdata)/len(data)
zlib compression ratio: 0.98
In [42]: bz2data = bz2.compress(data, 9)
In [43]: print 'bz2 compression ratio: ',1.-1.*len(bz2data)/len(data)
bz2 compression ratio: 0.959166666667
予想どおり、最良のケースは非常に良好で、圧縮率は 95% を超えています。
最悪のシナリオ (ランダム化されたデータ):
In [44]: randdata = '|'.join(['{:.3f}'.format(x) for x in np.random.randn(200)])
In [45]: zdata = zlib.compress(randdata, 9)
In [46]: print 'zlib compression ratio: ',1.-1.*len(zdata)/len(data)
zlib compression ratio: 0.5525
In [47]: bz2data = bz2.compress(randdata, 9)
In [48]: print 'bz2 compression ratio: ',1.-1.*len(bz2data)/len(data)
bz2 compression ratio: 0.5975
驚くべきことに、圧縮率が 60% までの最悪の場合でもそれほど悪くはありませんが、メモリが 8 GB しかない場合 (15 GB の 60% は 9 GB) は問題になる可能性があります。