16

私はここで、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
4

3 に答える 3

6

ここではダウンサンプリングが良い解決策です。10Mポイントをプロットすると、matplotlibで大量のメモリと時間が消費されます。許容できるメモリの量がわかっている場合は、その量に基づいてダウンサンプリングできます。たとえば、1Mポイントが23 MBの追加メモリを必要とし、スペースと時間の観点から許容できると判断した場合、常に1Mポイントを下回るようにダウンサンプリングする必要があります。

if(len(a) > 1M):
   a = scipy.signal.decimate(a, int(len(a)/1M)+1)
pylab.plot(a)

または、上記のスニペットのようなもの(上記はあなたの好みにはあまりにも積極的にダウンサンプリングする可能性があります)。

于 2011-06-14T15:49:08.920 に答える
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、これは極端な計算機能の一例にすぎません。

PS numpy「ストライドトリック」を使用すると、形状変更中にデータをコピーすることを回避できるはずです。

于 2013-07-15T22:53:56.133 に答える
1

対数サンプリングされたプロットの片側を保存することに興味があったので、これを思いつきました:(ダウンサンプルが私の最初の試みです)

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()

テスト

于 2019-05-15T22:49:43.930 に答える