Ошибка памяти в куче больших данных

Я новичок в python и программировании. Я пытаюсь построить карту ориентации с помощью python. У меня есть большое количество точек (около 1200 000) на плоскости, и каждый из них принадлежит кластеру. Каждый кластер должен иметь разный цвет. То, что я делаю в настоящее время, присваивает цвет каждому кластеру и рисует заполненный круг в каждой точке. Я попытался сделать это по частям, создав графики для разных сегментов и используя смесь, чтобы объединить их. Это код для части: (sn - общее количество точек, метка - это кластерный массив номера кластера, а xcoor и ycoor - координаты точки)

pylab.xlim([0,250])
pylab.ylim([0,100])
plt.savefig("HK pickle.png")
for l in range (1, 20):
    for j in range(int((float(sn)/80)*(l-1)), int((float(sn)/80)*(l))):
        overlay = Image.open("HK pickle.png")
        c = label[j] % 8
        if c == 0:
            circle1 = plt.Circle((float(xcoor[j]), float(ycoor[j])), 0.05, color = (0.5, 0, 0))
        elif c == 1:
            circle1 = plt.Circle((float(xcoor[j]), float(ycoor[j])), 0.05, color = (1, 0, 0))
        elif c == 2:
            circle1 = plt.Circle((float(xcoor[j]), float(ycoor[j])), 0.05, color = (0, 0.5, 0))
        elif c == 3:
            circle1 = plt.Circle((float(xcoor[j]), float(ycoor[j])), 0.05, color = (0, 1, 0))
        elif c == 4:
            circle1 = plt.Circle((float(xcoor[j]), float(ycoor[j])), 0.05, color = (0, 0, 0.5))
        elif c == 5:
            circle1 = plt.Circle((float(xcoor[j]), float(ycoor[j])), 0.05, color = (0, 0 ,1))
        elif c == 6:
            circle1 = plt.Circle((float(xcoor[j]), float(ycoor[j])), 0.05, color = (0.5, 0.5 ,0))
        elif c == 7:
            circle1 = plt.Circle((float(xcoor[j]), float(ycoor[j])), 0.05, color = (0.5, 0 ,0.5))
        fig = plt.gcf()
        fig.gca().add_artist(circle1)
        del circle1
    plt.savefig("HK pick.png")
    del fig
    back = Image.open("HK pick.png")
    comp = Image.blend(back, overlay, 0.5)
    comp.save("HK pickle.png", "PNG")
    del comp
pylab.xlim([0,250])
pylab.ylim([0,100])
plt.savefig("HK plots.png")

Однако это приводит к следующей ошибке:

    fig.gca().add_artist(circle1)
  File "C:\Python27\lib\site-packages\matplotlib\axes.py", line 1404, in add_artist
    self.artists.append(a)
MemoryError

Ошибка возникает при l = 11. Я продолжал проверять диспетчер задач параллельно, и у него по-прежнему было почти 3 ГБ свободной памяти при появлении MemoryError. Пожалуйста, помогите мне с этим.

Я новичок в этом и до сих пор не знаю, достаточно ли информации, которую я вам дал. пожалуйста, дайте мне знать, если вам нужна дополнительная информация

1
nl ja de

2 ответы

Вы можете сделать лучше с scatter и ключевым словом rasterized = True , который сгладит всю векторную графику до растрового изображения (что займет меньше памяти).

Что-то вроде:

colors_lst = [ ... your tuples ...]
color = map(lambda x: colors_lst[x % 8], labels)
ax.scatter(xcoord, ycoord, c = colors, rasterized=True)

Я думаю, что заменит большую часть вашего скрипта.

документация

1
добавлено
@ user2018858 Они могут быть любыми, с которыми matplotlib может иметь дело с цветом.
добавлено автор tacaswell, источник
Просто хочу подтвердить, что кортежи в цветах_lst должны быть значениями RGB. Правильно?
добавлено автор user2018858, источник

Если вы используете 32-разрядную ОС или запускаете 32-разрядный питон, вы не сможете эффективно работать с большими наборами данных (установка 64-битного python, numpy, matplotlib и т. Д. Может исправить это).

Тем не менее, я бы предложил сначала попытаться сделать снимок с более низким разрешением и посмотреть, будет ли это работать для вас (результаты могут быть достаточно хороши ). Например, я бы сначала заменил итератор j итератор для j в диапазоне (int ((float (sn)/80) * (l-1)), int ((float (sn)/80) * (l))): с чем-то вроде

for j in np.linspace(int((float(sn)/80)*(l-1)), int((float(sn)/80)*(l), num=20):
    j = int(j)

который даст вам диапазон значений 20 j в ваших пределах, но не для каждого целочисленного значения. Обратите внимание, что вам нужно будет указать j в int , поскольку это скорее всего будет np.float !

Другие замечания стиля менее полезны на данный момент, но в общем случае вам не нужно часто del - у python есть очень хороший сборщик мусора, который делает это за вас. Вы также можете установить свои пределы за пределами итераторов - это может сделать отладку более простой:

start_j = int((float(sn)/80)*(l-1)))
end_j = int((float(sn)/80)*(l))
for j in np.linspace(start_j, end_j, num=20):
    etc.
0
добавлено
Python
Python
7 654 участник(ов)

Уютный чат для профессионалов, занимающихся поиском питоньих мудростей. Как не получить бан: https://t.me/ru_python/577926

Python beginners
Python beginners
4 449 участник(ов)

Вопросы про Python для чайников. Cпам и троллинг неприемлем. Не злоупотребляйте стикерами. Частозадаваемые вопросы: https://github.com/ru-python-beginners/faq/blob/master/README.md Статистика тут: https://grstats.me/chat/x4qym2k5uvfkr3al6at7

pro.python
pro.python
1 090 участник(ов)

Сообщество разработчиков под Python Создатель: @rodgelius

Rude Python
Rude Python
971 участник(ов)

Python без „девочек”, здесь матерятся и унижают Django. Not gay friendly. Правила: t.me/rudepython/114107 @rudepython | t.me/rudepython

rupython
rupython
509 участник(ов)

Группа создана с целью оперативного получения ответов на возникающие вопросы по разработке на яп python, смежные темы, а также человеческого общения. Приветствую!

Python-programming
Python-programming
266 участник(ов)

Чат группы вконтакте https://vk.com/python_community