2016-12-04 12 views
0

別のプロジェクトで使用するために、json形式のダミーデータが必要です。数百万のjsonデータをPythonで生成する

from json import dumps 
from faker import Faker 
import collections 

database = [] 
filename = '1M' 
length = 1000000 
fake  = Faker() # <--- Forgot this 

for x in range(length): 
    database.append(collections.OrderedDict([ 
     ('last_name', fake.last_name()), 
     ('first_name', fake.first_name()), 
     ('street_address', fake.street_address()), 
     ('email', fake.email()) 
    ])) 

with open('%s.json' % filename, 'w') as output: 
    output.write(dumps(database, indent=4)) 
print "Done." 

このコードは動作しますが、それは非常に遅いです:私は現在、以下のコードでFakerパッケージを使用しています。私はPyPyを試しましたが、私は結果によって吹き飛ばされました。私は現在、600万秒で約220MBの100万データを持つjsonファイルを生成することができます。問題は、たとえば、2百万個のデータのように、さらに1200秒後に終了すると予想されるスクリプトで、この例外を越えてスクリプトが実行され、この例外で挨拶されます。MemoryError私はそれがPYPY_GC_MAXで何かを持っていると信じていますが、再び2Mファイルは440メガバイトを重くすべきです。

この問題を解決しようとしているうちに、私はまだ生成時間をさらに絞り込む方法を探しています。私はリストの理解を試しました、map()、結果はforループと同じでした。

おかげ

+0

使用するPythonはどれですか? –

+0

Python 2.7.12 32bits – Be0wulf

+0

あなたは 'OrderedDict'を使う必要がありますか?おそらく時間が増えるでしょう。 –

答えて

0

最初にデータベース全体を生成してからデータベースをダンプするため、メモリが不足します。よりメモリに優しい方法は、その場でdictエントリを生成することです。より良い方法は、オンザフライでエントリを作成するgeneratorを使用することです。

def fake_person_generator(length): 
    for x in range(length): # xrange in Python 2.7 
     yield OrderedDict([ 
      ('last_name', 'lastname_%i' % x), 
      ('first_name', 'firstname_%i' % x), 
      ('street_address', 'adress_%i' % x), 
      ('email', 'email_%i' % x)]) 

Alex Hallの答えと組み合わせると、メモリの必要性が大幅に軽減されます。

私はとてもよくJSONモジュールを知らないが、何かのように書き込みは次のようになります。あなたはOrderedDictを使用する必要はありません

length = 1000000 
fpg = fake_person_generator(length) 
with open('%s.json' % filename, 'w') as output: 
    for person in fpg: 
     json.dump(person, output) 
print "Done." 
+0

あなたはドンしません。 –

+0

OPの現在のコードはJSON配列を生成するので、これは広告を生成します(この形式は良い方法かもしれませんが)。リストを作成するには、たとえば、余分なカンマや角カッコを手動で書くことができます。 –

+0

ありがとう[結果](http://i.imgur.com/27tcRWB.png) – Be0wulf

1

代わりのoutput.write(json.dumps(database))、繰り返しメモリ内の大規模な文字列を作成せずにファイルにJSONを書くためにjson.dump(database, output)を使用しています。

+0

2Mで今すぐ試してみましょう – Be0wulf

+0

:([MemoryError' [Image] – Be0wulf

+0

@ Be0wulfこの段階での問題はJSONではなく、巨大なリストです!Maartenの答えと私のコメントを参照してください。 –

0

:JSON形式はないかもしれない(としません)順序を保存のアイテム。注文がファイルに保存されていても、別のプロジェクトがそのファイルを解析すると破損します。

dictを使用するだけです。また、はるかに速くなります。

アイテムの順序を保存するには、各エレメントのインデックスを明示的に保持する必要があります。このように:

from json import dumps 
from faker import Faker 
import collections 
import json 

def fake_person_generator(length, fake): 
    for x in range(length): # xrange in Python 2.7 
     yield {'last_name': fake.last_name(), 
       'first_name': fake.first_name(), 
       'street_address': fake.street_address(), 
       'email': fake.email(), 
       'index': x} 

database = [] 
filename = '1M' 
length = 1000000 
fake  = Faker() # <--- Forgot this 
fpg = fake_person_generator(length, fake) 
with open('%s.json' % filename, 'w') as output: 
    output.write('[') # to made json file valid according to JSON format 
    for person in fpg: 
     json.dump(person, output) 
    output.write(']') # to made json file valid according to JSON format 
print "Done." 
+0

私は自分の人生を楽にするために、最初から始めなければならないので、注文が保存されていないことを知っています。使用するテンプレートの種類を持っている。 – Be0wulf

関連する問題