Ошибка памяти при работе с большими данными - PullRequest
1 голос
/ 16 октября 2011

Я хотел бы нарисовать гистограмму, используя matplotlib.Однако из-за огромных данных (список, содержащий около 100 000 чисел), которые я отправил в функцию hist (), при рисовании двух фигур возникнет ошибка.Но все идет гладко, пока рисует только один из двух графиков.Может ли кто-нибудь помочь мне справиться с этим?Заранее спасибо.

Вот упрощенный код для отображения ошибки:

f_120 = plt.figure(1)
plt.hist(taccept_list, bins=6000000, normed = True, histtype ="step", cumulative = True, color = 'b', label = 'accepted answer')
plt.hist(tfirst_list, bins=6000000, normed = True, histtype ="step", cumulative = True, color = 'g',label = 'first answer')
plt.axvline(x = 30, ymin = 0, ymax = 1, color = 'r', linestyle = '--', label = '30 min')
plt.axvline(x = 60, ymin = 0, ymax = 1, color = 'c', linestyle = '--', label = '1 hour')
plt.legend()

plt.ylabel('Percentage of answered questions')
plt.xlabel('Minutes elapsed after questions are posted')
plt.title('Cumulative histogram: time elapsed \n before questions receive answer (first 2 hrs)')
plt.ylim(0,1)
plt.xlim(0,120)
f_120.show()
f_120.savefig('7month_0_120.png', format = 'png' )
plt.close()

f_2640 = plt.figure(2)
plt.hist(taccept_list, bins=6000000, normed = True, histtype ="step", cumulative = True, color = 'b', label = 'accepted answer')
plt.hist(tfirst_list, bins=6000000, normed = True, histtype ="step", cumulative = True, color = 'g',label = 'first answer')
plt.axvline(x = 240, ymin = 0, ymax = 1, color = 'r', linestyle = '--', label = '4 hours')
plt.axvline(x = 1440, ymin = 0, ymax = 1, color = 'c', linestyle = '--', label = '1 day')
plt.legend(loc= 4)

plt.ylabel('Percentage of answered questions')
plt.xlabel('Minutes elapsed after questions are posted')
plt.title('Cumulative histogram: time elapsed \n before questions receive answer (first 48)')
plt.ylim(0,1)
plt.xlim(0,2640)
f_2640.show()
f_2640.savefig('7month_0_2640.png', format = 'png' )

Ниже приводится подробное описание ошибки:

plt.hist (tfirst_list, bins =6000000, normed = True, histtype = "шаг", кумулятивный = True, цвет = 'g', метка = 'первый ответ')

Файл "C: \ software \ Python26 \ lib \ site-packages \"matplotlib \ pyplot.py ", строка 2160, в исторических значениях ret = ax.hist (x, ячейки, диапазон, нормированные, веса, совокупные значения, дно, показатель типа, выравнивание, ориентация, rwidth, log, цвет, метка, ** kwargs)

Файл "C: \ software \ Python26 \ lib \ site-packages \ matplotlib \ axes.py", строка 7775, в истории закрыт = False, edgecolor = c, fill = False))

Файл "C: \ software \ Python26 \ lib \ site-packages \ matplotlib \ axes.py", строка 6384, заполнение для poly в self._get_patches_for_fill (* args, ** kwargs):

Файл "C: \ software \ Python26 \ lib \ site-packages \ matplotlib \ axes.py", строка 317, в _grab_next_args для сегмента в self._plot_args (остальное, kwargs):

Файл "C: \программное обеспечение \ Python26 \ Lib \ сайт-Packages \ matplotlib \ axes.py ", строка 304, в _plot_args seg = func (x [:, j% ncx], y [:, j% ncy], kw, kwargs)

Файл" C:\ software \ Python26 \ lib \ site-packages \ matplotlib \ axes.py ", строка 263, в _makefill (x [:, np.newaxis], y [:, np.newaxis])),

Файл "C: \ software \ Python26 \ lib \ site-packages \ numpy \ core \ shape_base.py", строка 270, в hstack, возвращает _nx.concatenate (map (atleast_1d, tup), 1)

MemoryError

Ответы [ 2 ]

3 голосов
/ 16 октября 2011

Как уже отмечалось, шесть миллионов корзин звучат не очень полезно. Но простая вещь состоит в том, чтобы повторно использовать одну и ту же фигуру: поскольку изменяются только элементы графика, а не гистограммы, попробуйте что-то вроде этого:

vline1 = plt.axvline(...)
vline2 = plt.axvline(...)
lgd = legend()

и после savefig не закрывайте фигуру и не создавайте новые гистограммы, а используйте ее повторно, изменяя то, что нужно изменить:

# change vline1 and vline2 positions and labels
vline1.set_data([240,240],[0,1])
vline1.set_label('new label')
vline2.set_data(...)
vline2.set_label(...)
# remove old legend, replace with new
lgd.remove()
lgd = plt.legend(loc=4)
plt.xlabel('new xlabel')
# etc

Наконец, снова вызовите savefig с новым именем файла.

0 голосов
/ 19 октября 2011

Вы строите 6 миллионов корзин, а затем увеличиваете (предположительно) небольшую часть этого.С двумя строками на цифру это 12 миллионов точек данных, и я не удивляюсь, что matplotlib вылетает, когда вы пытаетесь построить еще 12 миллионов на следующем рисунке.Я очень сомневаюсь, что вам действительно нужно шесть миллионов бинов, поэтому давайте попробуем уменьшить гистограмму до более удобного размера!

Допустим, ваши данные охватывают те 44 или 48 часов, на которые вы хотите посмотреть.Тогда с шестью миллионами ячеек это будет означать, что ваши данные будут иметь разрешение 30 миллисекунд.Учитывая разрешение минут, которое вы отображаете, это кажется неразумным.Кроме того, у вас есть разрешение в секундах, поэтому 6 миллионов ячеек означают, что ваши данные охватывают 70 дней, но вы рассматриваете только два из них.

Предположим, вас интересуют данные за два дня с разрешением вв секундах или минутах.

Хотя вы задаете ячейки как количество корзин, вы также можете указать диапазон значений.Таким образом, для вашего первого графика вы могли бы сказать

plt.hist(taccept_list, bins=range(120), normed = True, histtype ="step", cumulative = True, color = 'b', label = 'accepted answer')
plt.hist(tfirst_list, bins=range(120), normed = True, histtype ="step", cumulative = True, color = 'g',label = 'first answer')

, давая вам разрешение в минутах в течение первых 120 минут.Гистограмма будет игнорировать все, что выше 120, что нормально, так как вы все равно не собираетесь показывать это на своем графике.

Альтернатива для разрешения в секундах может быть:

numpy.linspace(0,120,7200)

Теперьколичество точек в вашей гистограмме намного более разумно и, вероятно, больше соответствует данным, которые вы просматриваете / отображаете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...