python json.dump 生成的文件过大

0 投票
2 回答
2906 浏览
提问于 2025-04-18 12:14

我有一个大约380 MB的csv文件。我创建了一个空的数据结构,长得像这样:{ ID1 { day1 : [ [流量,小时1],[流量,小时2] ...[流量,小时23]], day2: [...]...day30:[...]}, ID2...}。我从csv文件中提取数据,并用下面的循环把这个结构填满,这个过程大约花了3分钟。总共有大约2000个ID,每个ID有30天的数据,每天24小时的数据。然后,当我尝试把这个填满的数据结构保存到一个json文件时,花了好几个小时,输出文件的大小超过了3 GB,我才停止了这个脚本。因为JSON应该是比较紧凑的格式,这种情况正常吗?我试过小规模的数据(1000条记录),效果很好。有没有什么好的方法来处理这个问题?谢谢。

注意:'stations'是一个站点的列表,row['ID']应该与这个列表匹配。

import csv
import json, pprint, datetime, time



meta_f = open( metadata_path , 'rb' )
meta_read = csv.DictReader(meta_f,delimiter='\t')


hour_f = open(hourly_path,'r')
hour_read = csv.DictReader(hour_f, delimiter=',')



stations = []
no_coords = []
for i,row in enumerate(meta_read):    
    if not row['Longitude'] or not row['Latitude']:
        no_coords.append(row['ID'])                
    elif in_box(row,bound):
        stations.append(row['ID'])

data={} 
number_of_days=30
days={}
for i in range(1,number_of_days+1):
    days[i]=[]    
for station in stations:
    data[int(station)]=days 


with open('E:/pythonxy/Projects/UP/json_data.txt','wb') as f:
    json.dump({},f)
    f.close()
with open('E:/pythonxy/Projects/UP/json_data.txt','rb') as f:
    d=json.load(f)    

#i=0
t0=time.time()    
for row in hour_read:
    #if i>1000:
        #break
    if row['Station'] in stations:
        #print row['Station']         
        t=datetime.datetime.strptime(row['TimeStamp'], '%m/%d/%Y %H:%M:%S')
        data[int(row['Station'])][int(t.day)]+=[[row['TotalFlow'],t.hour]]
    #i+=1
    #print i
d.update(data)
print time.time()-t0

t0=time.time()
with open('E:/pythonxy/Projects/UP/json_data.txt','wb') as f:
    json.dump(d,f)
    f.close()
print time.time()-t0    

print 'DONE'

2 个回答

2

这其实不是一个直接的答案,但JSON格式的数据比CSV格式的数据要大得多。我们来看一个例子。

CSV格式:

X,Y,Z
1,2,3
4,5,6

JSON格式:

[{X:1,Y:2,Z:3},{X:4,Y:5,Z:6}]

CSV格式的数据占用17个字节,而JSON格式的数据占用29个字节!

2
for station in stations:
    data[int(station)]=days
from copy import deepcopy
for station in stations:
    data[int(station)] = deepcopy(days)

在这个循环中,你每次创建的 data 里的条目都指向同一个字典作为值。这就意味着,每当你往任何一个 data[something] 字典里添加东西时,其实是把东西加到了所有的字典里。这样一来,当你把它保存到文件里时,结果就会变得不对劲,而且数据量会很大。为了避免这种情况,你可以对 days 字典进行深拷贝:

撰写回答