Пустой пустой массив меняет значение после создания обычного массива - PullRequest
0 голосов
/ 30 мая 2019

Я прочитал на официальной странице о том, что существует альтернатива созданию инициализированного массива без использования только нулей:

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

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

import numpy as np

def getInitialisedArray():
    return np.empty((), dtype=np.float).tolist()

def createFloatArray(x):
    return np.array(float(x))

Если я просто вызываю getInitialisedArray() самостоятельно, здесьэто то, что он выводит:

>>> getInitialisedArray()
0.007812501848093234

И если я просто вызываю функцию createFloatArray():

>>> createFloatArray(3.1415)
3.1415

Все это выглядит нормально, но если я повторю тест и вызову getInitialisedArray() после создания массива с плавающей точкой возникает проблема:

print(getInitialisedArray())
print(createFloatArray(3.1415))
print(getInitialisedArray())

Вывод:

>>>
0.007812501848093234
3.1415
3.1415

Кажется, что второй вызов для получения инициализированного массива получаетто же значение, что и в нормальном np.array().Я не понимаю, почему это происходит.Разве они не должны быть отдельными массивами, которые не имеют связи между собой?

--- Обновление ---

Я повторил это и изменил размер пустогомассив:

import numpy as np

def getInitialisedArray():
    # Changed size to 2 x 2
    return np.empty((2, 2), dtype=np.float).tolist()

def createFloatArray(x):
    return np.array(float(x))

print(getInitialisedArray())
print(createFloatArray(3.1415))
print(getInitialisedArray())

Вывод:

[[1.6717403e-316, 6.9051865033801e-310], [9.97338022253e-313, 2.482735075993e-312]]
3.1415
[[1.6717403e-316, 6.9051865033801e-310], [9.97338022253e-313, 2.482735075993e-312]]

Это такой вывод, который я ожидал, но здесь он работает, потому что я изменил размер.Влияет ли размер теперь, если пустой массив принимает то же значение, что и обычный np.array()?

Ответы [ 2 ]

1 голос
/ 30 мая 2019

Из документации , np.empty () "вернет новый массив заданной формы и типа без инициализации записей". Это должно означать, что он просто выделит место в памяти для переменной, которой он назначен. Какими бы ни были данные в пространстве памяти, они не будут изменены.

В первом примере вы печатаете возврат из getInitialisedArray, фактически не сохраняя его. Затем Python должен знать, что вы не сохранили адрес этого значения. Затем python сохранит этот адрес для следующего значения, которому нужен адрес. Поскольку createFloatArray также не хранит адрес, значение в адресе будет изменено на 3.1415, и python сохранит адрес для следующего назначения. Когда вы снова вызовете getInitialisedArray, он снова использует этот адрес и распечатает 3.1415. Однако если вы измените тип данных (например, измените размеры массива), в зависимости от того, как python обрабатывает этот тип данных, ему может потребоваться больше блоков памяти и получить другой адрес. Теоретически, если createFloatArray имеет ту же форму, что и getInitialisedArray, он может иметь такое же поведение.

ВНИМАНИЕ! Я очень рекомендую не делать этого. Возможно, что python или ваша система в целом выполнят задачу между этими двумя операциями, которая изменит адрес памяти между вызовами, даже если это один и тот же тип данных.

0 голосов
/ 30 мая 2019

Проверьте id() для каждого массива после его инициализации. np.empty() создает пространство, которое позже можно использовать после инициализации массива той же формы.

для большего понимания: print(np.array(float(1)) print(np.empty((),dtype=np.float).tolist())

то же самое, но присвоение переменным: x = np.array(float(1)) y = np.empty((),dtype=np.float).tolist() print(x) print(y)

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