2014-05-15 2 views
0

나는 각각의 json 파일을 약 1.5gb로하여 하나의 csv (R로로드)로 결합하여 출력 할 json 파일을 다수 보유하고 있습니다. 각 250mb에서 4-5 개의 json 파일에 대한 시험판을 작성하는 동안 다음 오류가 발생합니다. 나는 8GB RAM과 Windows 7 Professional 64 비트에서 Python 버전 '2.7.6 (default, Nov 10 2013, 19:24:18) [MSC v.1500 32 bit (Intel)]'을 실행 중입니다.Python의 MemoryError : 코드를 최적화하려면 어떻게해야합니까?

저는 파이썬 초보자이며 최적화 된 코드를 작성해 본 경험이 거의 없으며 아래에서 스크립트를 최적화 할 수있는 방법에 대한 지침을 알려 주시면 감사하겠습니다. 고맙습니다!

======= 파이썬 MemoryError의의 =======

Traceback (most recent call last): 
    File "C:\Users\...\tweetjson_to_csv.py", line 52, in <module> 
    for line in file: 
MemoryError 
[Finished in 29.5s] 

======= JSON CSV로 변환 스크립트 =======

# csv file that you want to save to 
out = open("output.csv", "ab") 

filenames = ["8may.json", "9may.json", "10may.json", "11may.json", "12may.json"] 
open_files = map(open, filenames) 

# change argument to the file you want to open 
for file in open_files: 
    for line in file: 
     # only keep tweets and not the empty lines 
     if line.rstrip(): 
      try: 
       tweets.append(json.loads(line)) 
      except: 
       pass 

for tweet in tweets: 
    ids.append(tweet["id_str"]) 
    texts.append(tweet["text"]) 
    time_created.append(tweet["created_at"]) 
    retweet_counts.append(tweet["retweet_count"]) 
... ... 

print >> out, "ids,text,time_created,retweet_counts,in_reply_to,geos,coordinates,places,country,language,screen_name,followers,friends,statuses,locations" 
rows = zip(ids,texts,time_created,retweet_counts,in_reply_to_screen_name,geos,coordinates,places,places_country,lang,user_screen_names,user_followers_count,user_friends_count,user_statuses_count,user_locations) 

csv = writer(out) 

for row in rows: 
    values = [(value.encode('utf8') if hasattr(value, 'encode') else value) for value in row] 
    csv.writerow(values) 

out.close() 
여기
+5

당신은 메모리에 모든 것을 ('tweets.append (json.loads (선))')로드하고 있습니다. 각 라인을 읽은 직후'output.csv'에 쓰는 것과 같은 방식으로 알고리즘을 구사할 수 있습니까? – univerio

+2

이것은 아마도 http://codereview.stackexchange.com에 더 적합 할 것입니다. – dano

+0

그러나 여기에있는 동안 한 번에 하나씩 파일을 열어야합니다. 한꺼번에 열 필요가 없습니다. 특히 당신이 그들과 함께 끝났을 때 당신이 그들을 닫지 않을 것이기 때문에. 덕분에 @ dano. – dano

답변

3

이 줄 :

open_files = map(open, filenames) 

한 번 동시에에서 모든 파일을 엽니 다.

그러면 모든 것을 읽고 동일한 단일 배열 tweets에 기록합니다.

그리고 두 개의 메인 루프가 있습니다. 따라서 각 짹짹 (몇 기가 바이트가 있습니다)은 번 반복됩니다. 번 두 번 깜박입니다! zip 함수에 추가 한 다음 파일에 쓰는 반복을했기 때문입니다. 이러한 포인트 중 하나가 메모리 오류의 원인 일 수 있습니다.

절대적으로 필요한 경우가 아니면 각 데이터 조각을 한 번만 터치 해보십시오. 파일을 반복하면서 라인을 처리하고 즉시 작성하십시오. 대신이 같은

시도 뭔가 :

out = open("output.csv", "ab") 

filenames = ["8may.json", "9may.json", "10may.json", "11may.json", "12may.json"] 

def process_tweet_into_line(line): 
    # load as json, process turn into a csv and return 
    return line 

# change argument to the file you want to open 
for name in file_names: 
    with open(name) as file: 
     for line in file: 
      # only keep tweets and not the empty lines 
      if line.rstrip(): 
       try: 
        tweet = process_tweet_into_line(line) 
        out.write(line) 
       except: 
        pass 
+0

@ Lego Stormtroopr에게 감사하지만 내 코드에서 제안 사항을 구현하는 데 약간의 어려움이 있습니다. 좀 더 제발 좀 도와 줄래? 감사! –

관련 문제