Как авторы numpy решают, помещать ли функцию в numpy. * Или numpy .ndarray. *? - PullRequest
1 голос
/ 05 мая 2020

Я чувствую, что мне здесь не хватает объединяющей темы. Есть несколько наблюдений, по которым у меня проблемы с контекстуализацией.

  1. flatten () находится в numpy .ndarray. *, Но flatten () на самом деле неуместен, что мне кажется немного странным, поскольку это метод объекта, а не библиотечная функция.

  2. Итак, если объектным методам разрешено возвращать копии, то почему np. repeat () (неуместно), а не просто объектный метод в np.ndarray. *?

  3. С другой стороны, не объектный метод numpy .reshape находится в- место ... эта тенденция кажется немного противоположной тому, что я ожидал.

  4. np.random.randn () принимает несколько позиционных аргументов для размеров массива, который вы хотите сгенерировать, тогда как np.zeros принимает кортеж с одним позиционным аргументом, который содержит размеры. Есть ли для этого причина?

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

Спасибо.

1 Ответ

2 голосов
/ 05 мая 2020
In [495]: x = np.arange(12).reshape(3,4)      # reshape((3,4)) also                                                         
In [496]: x.flatten?                                                                                   
Docstring:
a.flatten(order='C')
Return a copy of the array collapsed into one dimension.

ravel метод и функция «эквивалентны»:

In [497]: x.ravel?                                                                                     
Docstring:
a.ravel([order])
Return a flattened array.
Signature: np.ravel(a, order='C')
Docstring:
Return a contiguous flattened array.

A 1-D array, containing the elements of the input, is returned.  A copy is

делается только в случае необходимости.

По вашей терминологии flatten равно out-of-place, ravel нет. Или, выражаясь словами numpy's, ravel обычно дает view, а не copy.

Фактический код для np.ravel:

if isinstance(a, np.matrix):
    return asarray(a).ravel(order=order)
else:
    return asanyarray(a).ravel(order=order)

Если Аргумент не является массивом, он превращается в один. Затем используется метод.

Этот шаблон довольно распространен. При необходимости функция выполняет asarray, а затем делегирует действие методу.

np.reshape и x.reshape следуют этому шаблону. Существует форма x.shape=..., которая является настоящим действием in-place. Они возвращают view, где это возможно (они не меняют общее количество элементов). Этот view разделяет данные, но имеет свои собственные shape и strides.

resize - одна из пар функция / метод, которая имеет существенные различия между ними. Мы не часто его используем.

Функция repeat такая же, как и метод. Поскольку обычно изменяется количество элементов, repeat (обе формы) возвращает новый массив со своими данными. Он не возвращает view.

sum - это еще одна пара, которая возвращает новый массив. Он изменяет количество элементов, поэтому view невозможно.

Что касается randn, это документация объясняет разницу. Указание shape как кортежа вполне может быть предпочтительным «стандартом», но такое поведение randn необычно. Предлагаемая альтернатива для нового кода standard_normal принимает кортеж size. reshape принимает любой.

В то время как обычный синтаксис кортежа - (1,2,3), () фактически необязательны; это запятая, которая отмечает кортеж. Это требуется в кортеже из 1 элемента, например. (1,). При индексировании x[(1,2)] и x[1,2] совпадают, а tuple передается x.__getitem__.

Оба python и numpy имеют длинную историю. Выбор, сделанный в прошлом, так или иначе остается с нами. Доработка кода идет медленно; добавлять функции проще, чем удалять их.

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