2015-05-07 54 views
3

我正在从数据库中检索大量数据,我稍后使用散点图进行绘图。但是,我用完了内存,当我使用完整数据时程序中止。为了记录,运行该程序需要大于30分钟,数据列表的长度大约为20-30百万。当绘图时内存不足,Python

map = Basemap(projection='merc', 
resolution = 'c', area_thresh = 10, 
llcrnrlon=-180, llcrnrlat=-75, 
urcrnrlon=180, urcrnrlat=82) 

map.drawcoastlines(color='black') 
# map.fillcontinents(color='#27ae60') 
with lite.connect('database.db') as con: 
    start = 1406851200 
    end = 1409529600 
    cur = con.cursor() 
    cur.execute('SELECT latitude, longitude FROM plot WHERE unixtime >= {start} AND unixtime < {end}'.format(start = start, end = end)) 
    data = cur.fetchall() 
    y,x = zip(*data) 
    x,y = map(x,y) 
    plt.scatter(x,y, s=0.05, alpha=0.7, color="#e74c3c", edgecolors='none') 
    plt.savefig('Plot.pdf') 
    plt.savefig('Plot.png') 

我想我的问题可能在zip(*)函数中,但我真的没有线索。我对如何通过重写现有代码来保存更多内存以及分解绘图过程感兴趣。我的想法是将时间段分成两半,然后在保存该数字之前在两个时间段内两次做同样的事情,但是我不确定这会对我有所帮助。如果问题实际上是阴谋,我不知道。

+1

只是出于好奇,len(data)的输出是什么? –

+0

目前我无法给出准确的答案,因为它正在运行,但我估计它是大约24-30万美元。 @nivixzixer – bjornasm

+1

O.O在这种情况下,你可以尝试“流”数据?一次处理几百个绘图点,直到您看到完整的图像,而不是将所有3000万个内存加载到内存中? –

回答

2

如果您认为问题在于函数zip,为什么不使用matplotlib数组将数据转换为正确的格式呢?事情是这样的:

data = numpy.array(cur.fetchall()) 
lat = data[:,0] 
lon = data[:,1] 
x,y = map(lon, lat) 

此外,您生成的PDF会非常大,由慢的各种PDF阅读器渲染,因为它是默认的矢量格式。所有数百万个数据点将以浮点形式存储并在用户打开文档时呈现。我建议您将rasterized=True参数添加到您的plt.scatter()调用中。这会将结果保存为位图内的位图(请参阅文档here

如果这一切都无济于事,我将通过注释掉后面的行来进一步调查。也就是说,首先注释掉plt.savefig('Plot.png')并查看内存使用是否下降。如果没有,在此之前注释掉该行,等等。