我读过here matplotlib擅长处理大型数据集。我正在编写一个数据处理应用程序并将matplotlib图形嵌入到wx中,并且发现matplotlib在处理大量数据方面是可怕的,无论是在速度方面还是在内存方面。有没有人知道一种方法来加速(减少matplotlib的内存占用),而不是下采样你的输入?
为了说明matplotlib与内存有多糟糕,请考虑以下代码:
import pylab
import numpy
a = numpy.arange(int(1e7)) # only 10,000,000 32-bit integers (~40 Mb in memory)
# watch your system memory now...
pylab.plot(a) # this uses over 230 ADDITIONAL Mb of memory
答案 0 :(得分:4)
下采样是一个很好的解决方案 - 在matplotlib中绘制10M点消耗大量内存和时间。如果您知道可以接受多少内存,那么您可以根据该数量进行下采样。例如,假设1M点需要23个额外的MB内存并且您发现它在空间和时间方面是可接受的,因此您应该进行缩减采样以使其始终低于1M点:
if(len(a) > 1M):
a = scipy.signal.decimate(a, int(len(a)/1M)+1)
pylab.plot(a)
或者类似上面的代码片段(上面的内容可能会根据您的喜好进行下调。)
答案 1 :(得分:1)
我经常对极端值感兴趣,在绘制大块数据之前,我会这样做:
import numpy as np
s = np.random.normal(size=(1e7,))
decimation_factor = 10
s = np.max(s.reshape(-1,decimation_factor),axis=1)
# To check the final size
s.shape
当然np.max
只是极端计算功能的一个例子。
P.S。
随着numpy
“大踏步”,应该可以避免在重塑期间复制数据。
答案 2 :(得分:0)
我有兴趣保存对数抽样图的一侧,所以我想到了这一点: (降采样是我的第一次尝试)
def downsample(x, y, target_length=1000, preserve_ends=0):
assert len(x.shape) == 1
assert len(y.shape) == 1
data = np.vstack((x, y))
if preserve_ends > 0:
l, data, r = np.split(data, (preserve_ends, -preserve_ends), axis=1)
interval = int(data.shape[1] / target_length) + 1
data = data[:, ::interval]
if preserve_ends > 0:
data = np.concatenate([l, data, r], axis=1)
return data[0, :], data[1, :]
def geom_ind(stop, num=50):
geo_num = num
ind = np.geomspace(1, stop, dtype=int, num=geo_num)
while len(set(ind)) < num - 1:
geo_num += 1
ind = np.geomspace(1, stop, dtype=int, num=geo_num)
return np.sort(list(set(ind) | {0}))
def log_downsample(x, y, target_length=1000, flip=False):
assert len(x.shape) == 1
assert len(y.shape) == 1
data = np.vstack((x, y))
if flip:
data = np.fliplr(data)
data = data[:, geom_ind(data.shape[1], num=target_length)]
if flip:
data = np.fliplr(data)
return data[0, :], data[1, :]
这使我可以更好地保留情节的一侧:
newx, newy = downsample(x, y, target_length=1000, preserve_ends=50)
newlogx, newlogy = log_downsample(x, y, target_length=1000)
f = plt.figure()
plt.gca().set_yscale("log")
plt.step(x, y, label="original")
plt.step(newx, newy, label="downsample")
plt.step(newlogx, newlogy, label="log_downsample")
plt.legend()