#python #numpy
#python #numpy
Вопрос:
предположим, у нас есть два скаляра с типом numpy.float32:
a
>>>1.0
type(a)
>>><class 'numpy.float32'>
b
>>>2.0
type(b)
>>><class 'numpy.float32'>
Я пытаюсь создать массив NumPy из списка([А,Б,А,А,Б,Б,Б,А,Б,Б,А,А,А,Б,Б,а,а]).
Мой вопрос в том, можем ли мы заставить этот массив указывать свои скаляры на один и тот же объект в памяти? вместо того, чтобы копировать их за шаг его формы?
У меня есть очень длинный массив, например, shape (1,30000), который состоит из нескольких скаляров (около 30), упорядоченных в разных порядках, например, 1,2,3,2,1,3,2,2,1,3,3,2,2,3,1,2,1,3…
Создание этого массива требует огромного объема памяти, но поскольку на самом деле это повторяющиеся одни и те же скаляры, я подумал, что может быть способ загрузить их один раз в память и указать на них элементы массива.
Комментарии:
1. Что касается памяти, способ «оригинального копирования» фактически потреблял бы меньше памяти, 32 бита на элемент. Подход «указатель» сохранял бы указатель на число для каждого элемента, обычно сегодня 64 бита для каждого элемента
2. Массивы указателей (object dtype) занимают столько же памяти (если не больше), сколько числовые dtypes, и, как правило, с ними медленнее работать. Часто список (который также использует указатели) выполняется быстрее. Быстрый и эффективный скомпилированный код numpy написан для числовых dtypes.
3. @hpaulj да, это правильно. даже создание пустого массива с определенной формой и dtype будет занимать тот же объем памяти. вот как работает numpy. возможно, попробуйте вместо этого использовать списки, как вы сказали.
Ответ №1:
Один из способов, который может помочь вам сократить объем памяти вдвое, если размер вашего массива меньше 32767 (что является максимальным значением int16 в numpy, попробуйте: np.iinfo(np.int16).max
), — это сохранить массив индексов ваших значений как int16 вместо самого массива значений, со стоимостью вызова значения из другого списка. Хотя это будет почти бесполезно в том смысле, что вы не сможете использовать вычисления массива без создания массива значений:
values = np.array([1.0, 2.0, 3.0, 4.0], dtype=np.float32)
indices = np.array([1,2,3,2,1,3,2,1,2,1,3,3,2,2,3,1,2,1,1,3], dtype=np.int16)
Комментарии:
1. ну, бывают случаи, когда у меня есть значения с плавающей точкой. это не всегда целые числа.
2. индексы @kevaes всегда являются целыми числами (если они являются числами). Не принимайте индексы за значения. Они разные