Как я могу изменить словарь массивов / списков Python на месте, не увеличивая потребление памяти вдвое?

У меня есть словарь с множественными массивами в качестве значений. Я хочу изменить эти массивы, добавив в конце один дополнительный элемент. Поскольку массивы numpy для этого не подходят, я сначала конвертирую массивы в списки, а затем добавляю значение p в конец.

Однако, когда я запускаю эту функцию, потребление памяти удваивается, как если бы массивы были скопированы, а не изменены на месте.

Вот код:

def add_coordinates(my_Dict):
  n = 0
  for key in my_Dict.keys():
    # Convert values of each key to a list. In place?
    my_Dict[key] = [list(s) for s in my_Dict[key]]    
    del s
    for index in range(len(my_Dict[key])):
      p = [float(index)/len(my_Dict[key])]      
      my_Dict[key][index] = my_Dict[key][index] + p
    my_Dict[key] = np.array(my_Dict[key])
  return my_Dict

После предложения создать новый массив numpy с расширенным измерением, а затем добавить новое значение, я изменил код следующим образом:

def add_coordinates(my_Dict):
  for key in my_Dict.keys():
    tmp = np.zeros((my_Dict[key].shape[0],my_Dict[key].shape[1]+1))
    tmp[:,:-1] = my_Dict[key]
    for index in range(len(my_Dict[key])):
      tmp[index,-1] = float(index)/len(my_Dict[key])
    my_Dict[key] = tmp
  return my_Dict

В качестве третьего варианта я использую np.concatenate, чтобы добавить новое измерение в массивы th numpy:

def add_coordinates(my_Dict):
  for key in my_Dict.keys():
    coords = np.zeros((my_Dict[key].shape[0],1))
    for index in range(my_Dict[key].shape[0]):
      coords[index] = float(index)/my_Dict[key].shape[0]
    my_Dict[key] = np.concatenate((my_Dict[key],coords),axis=1)
  return my_Dict

Но np.concatenate также делает копию.

Все эти варианты удваивают требования к памяти. Есть ли способ сделать это без копирования исходных массивов и внести все изменения на месте?

Когда вы конвертируете в списки, вы делаете копию данных, для начала

juanpa.arrivillaga 29.11.2018 17:28

Почему бы вам не заменить свой массив numpy новым массивом на месте, т.е. создать массив с n + 1 значениями и my_dict [i] = newarray

Niteya Shah 29.11.2018 17:35

@NiteyaShah Я пробовал это (включил код в вопрос), но создание нового массива numpy для замены старого, похоже, не удаляет старый из памяти ...

hirschme 29.11.2018 17:49

Это похоже на возможный вариант использования numpy.append.

user2357112 supports Monica 29.11.2018 18:49

@ user2357112 numpy.append также генерирует копию .. так же, как numpy.insert

hirschme 29.11.2018 18:50

@hirschme: Да, но он копирует гораздо меньше, чем то, что вы делаете сейчас.

user2357112 supports Monica 29.11.2018 18:51

Это внутренняя проблема всех языков, в которых есть сборка мусора, и я не думаю, что есть какой-либо предлагаемый способ удаления объектов из памяти, единственные две вещи, о которых я могу думать сейчас, - это слабая ссылка на docs.python.org/3/library/weakref.html#example и сохранение большого массива numpy по умолчанию и вместо того, чтобы увеличивать его, просто замените его индексом, но я считаю, что это не очень эффективно с точки зрения памяти. Ссылка на объект Python почти всегда создает дубликаты, если это серьезная проблема, может быть, реализовать эту часть кода на C? Это, безусловно, будет хорошим приростом производительности

Niteya Shah 30.11.2018 00:01
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
7
51
0

Другие вопросы по теме