Numpy: Поддержка принуждения массива уток

Созданный на 25 июн. 2019  ·  55Комментарии  ·  Источник: numpy/numpy

Открытие этой проблемы после обсуждения с @shoyer , @pentschev и @mrocklin , о которых это обсуждалось в NEP 22 (так что я в основном повторяю здесь идеи других людей, чтобы возобновить обсуждение и исправить собственное недоразумение;).

Было бы полезно, чтобы в различных нижестоящих библиотеках массивов была функция, гарантирующая, что у нас есть некоторый утиный массив (например, ndarray ). Это было бы чем-то похоже на np.asanyarray , но без необходимости создания подклассов. Это позволило бы библиотекам возвращать свой собственный (утиный) тип массива . Если объект не поддерживает подходящее преобразование, мы можем вернуться к обработке подклассов ndarray , ndarray s и принуждения других вещей (вложенных списков) к ndarray s.

cc @njsmith (соавтор НЭП 22)

01 - Enhancement numpy.core

Самый полезный комментарий

Может быть quack_array :)

Все 55 Комментарий

Предлагаемая реализация будет выглядеть примерно так:

import numpy as np

# hypothetical np.duckarray() function
def duckarray(array_like):
  if hasattr(array_like, '__duckarray__'):
    # return an object that can be substituted for np.ndarray
    return array_like.__duckarray__()
  return np.asarray(array_like)

Пример использования:

class SparseArray:
  def __duckarray__(self):
    return self
  def __array__(self):
    raise TypeError

np.duckarray(SparseArray())  # returns a SparseArray object
np.array(SparseArray())  # raises TypeError

Здесь я использовал np.duckarray и __duckarray__ качестве заполнителей, но мы, вероятно, можем лучше использовать эти имена. См. Терминологию из NEP 22:

«Утиный массив» пока отлично работает в качестве заполнителя, но он довольно жаргонный и может сбить с толку новых пользователей, поэтому мы можем выбрать что-то другое для реальных функций API. К сожалению, «подобный массиву» уже используется для концепции «всего, что может быть преобразовано в массив» (включая, например, объекты списка), а «anyarray» уже используется для концепции «чего-то, что разделяет реализацию ndarray, но имеет другую семантику », которая противоположна массиву уток (например, np.matrix - это« любой массив », но не« массив уток »). Это классический навес для велосипедов, поэтому сейчас мы просто используем «утиный массив». Некоторые возможные варианты включают: arrayish, pseudoarray, nominalarray, ersatzarray, arraymimic,…

Некоторые другие варианты имен: np.array_compatible() , np.array_api() ....

np.array_compatible может работать, хотя я не уверен, что он мне нравится больше, чем duckarray . np.array_api Мне не нравится, неправильное представление imho.

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

Мне нравится слово «совместимость», возможно, мы можем придумать и другие варианты в этой строке as_compatible_array (что отчасти подразумевает, что все совместимые объекты являются массивами). as может раздражать (частично потому, что все функции as не имеют пробелов). «duck» кажется приятным в библиотеках, но я думаю, что это немного странно для случайных людей, видящих его. Так что я думаю, что мне не нравится «утка» тогда и только тогда, когда мы хотим, чтобы нижестоящие пользователи использовали его много (т.е. даже когда я начинаю писать небольшой инструмент для себя / небольшую лабораторию).

Может быть quack_array :)

Чтобы немного расширить тему, есть еще один случай, который не охвачен np.duckarray , а именно создание новых массивов с типом, основанным на существующем типе, аналогично тем, что функции, такие как np.empty_like делать. В настоящее время мы можем делать такие вещи:

>>> import numpy as np, cupy as cp
>>> a  = cp.array([1, 2])
>>> b = np.ones_like(a)
>>> type(b)
<class 'cupy.core.core.ndarray'>

С другой стороны, если у нас есть array_like , из которого мы хотели бы создать массив CuPy через API NumPy, это невозможно. Думаю, было бы полезно иметь что-то вроде:

import numpy as np, cupy as cp
a  = cp.array([1, 2])
b = [1, 2]
c = np.asarray(b, like=a)

Есть идеи / предложения по этому поводу?

Может, np.copy_like? Мы хотели бы тщательно определить, какие свойства
(например, включая dtype или нет) копируются из другого массива.

В пн, 1 июля 2019 г., 5:40 Петр Андреас Энтщев <
[email protected]> написал:

Чтобы немного расширить тему, есть еще один случай, который не рассматривается.
с np.duckarray, который создает новые массивы с типом на основе
для существующего типа, аналогично тому, что делают такие функции, как np.empty_like.
В настоящее время мы можем делать такие вещи:

импортировать numpy как np, cupy как cp >>> a = cp.array ([1, 2]) >>> b = np.ones_like (a) >>> type (b)

С другой стороны, если у нас есть array_like, который мы хотели бы создать
массив CuPy из API NumPy, это невозможно. Я думаю было бы
полезно иметь что-то вроде:

импортировать numpy как np, cupy как cp
a = cp.array ([1, 2])
б = [1, 2]
c = np.asarray (b, как = a)

Есть идеи / предложения по этому поводу?

-
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/numpy/numpy/issues/13831?email_source=notifications&email_token=AAJJFVRCWDHRAXHHRAXHHRDHXXM3P5H3LRA5CNFSM4H3HQWAKYY3PNVWWK3TUL52HSG63DFVREDNVWWK3TUL52HS4DVMVREK3TUL52HS4DFMVREK
или отключить поток
https://github.com/notifications/unsubscribe-auth/AAJJFVRSYHUYHMPWQTW2NLLP5H3LRANCNFSM4H3HQWAA
.

np.copy_like тоже неплохо звучит. Я согласен, у нас, скорее всего, должны быть способы контролировать такие вещи, как dtype .

Извините за вопрос новичка, но должно ли что-то вроде np.copy_like быть поправкой к NEP-22, должно ли это обсуждаться в списке рассылки, или какой подход к этому будет наиболее подходящим?

У нас на самом деле нет строгих правил по этому поводу, но я бы склонился к объединению np.copy_like и np.duckarray (или как мы это называем) в новый NEP по принуждению / созданию массивов уток, один это предписывает, как НЭП 18, а не «Информационное», как НЭП 22. Это не обязательно должно быть длинным, большая часть мотивации уже ясна из ссылки на НЭП 18/22.

Одно замечание о np.copy_like() : он обязательно должен выполнять диспетчеризацию с помощью __array_function__ (или чего-то подобного), поэтому такие операции, как np.copy_like(sparse_array, like=dask_array) могут быть определены для любого типа массива.

Отлично, спасибо за информацию, и я согласен с вашим предложением об отправке. Я буду работать над нэпом для реализации как np.duckarray и np.copy_like и на этой неделе отправлю проект PR для этого.

Здорово, спасибо, Питер!

В пн, 1 июля 2019 г., 9:29 Петр Андреас Энтщев <
[email protected]> написал:

Отлично, спасибо за информацию, и я согласен с вашим предложением об отправке. я
будет работать над NEP для реализации как np.duckarray, так и
np.copy_like и отправьте для этого черновик PR на этой неделе.

-
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/numpy/numpy/issues/13831?email_source=notifications&email_token=AAJJFVW2YUBNUCJZK6JWDBTP5IWHNA5CNFSM4H3HQWAKYY3PNVWWK3TUL52HS443LVMVREXDNVWWK3TUL52HS443DFMVREX
или отключить поток
https://github.com/notifications/unsubscribe-auth/AAJJFVR2KTPAZ4JPWDYYMFLP5IWHNANCNFSM4H3HQWAA
.

С удовольствием и большое спасибо за идеи и поддержку в этой работе!

Я думаю, что функции array_like и copy_like было бы немного странно иметь в основном пространстве имен, поскольку у нас не может быть реализации по умолчанию (по крайней мере, такой, которая будет правильной cupy / dask / sparse / и т. д.), верно? Они полезны только при переопределении. Или мне не хватает способа создать здесь произвольные объекты массива, отличные от numpy?

Это правда, они действительно будут полезны, только если вы хотите поддерживать утиный ввод. Но, безусловно, np.duckarray и np.copy_like будут работать, даже если аргументы представляют собой только массивы NumPy - они будут просто эквивалентны np.array / np.copy .

Все реализации массивов имеют метод copy верно? Использование этого вместо copy_like должно работать, так зачем добавлять новую функцию?

array_like Я вижу необходимость в этом, но мы можем обсудить, где это разместить.

np.duckarray для меня имеет смысл.

Я бы предпочел объединить np.copy_like и np.duckarray (или как мы его называем) в новый NEP по принуждению / созданию массивов уток, который является предписывающим, как NEP 18, а не «информационным», как NEP 22.

+1

array_like Я вижу необходимость в нем, но мы можем обсудить, где его разместить.

На самом деле это тот случай, который я хотел бы решить с помощью чего-то вроде np.copy_like . Я не тестировал, но, вероятно, np.copy уже отправляет правильно, если массив не является NumPy.

Для ясности, вы также имеете в виду функцию np.array_like ? Я намеренно избегал такого имени, потому что думал, что оно может сбивать с толку все существующие ссылки на array_like -массивы. Однако теперь я понимаю, что np.copy_like может означать необходимую копию, и я думаю, что было бы хорошо иметь поведение, подобное np.asarray , где копия происходит только в том случае, если это еще не NumPy массив. В случае, обсуждаемом здесь, лучше всего сделать копию, только если a не того же типа, что и b в вызове, таком как np.copy_like(a, like=b) .

Я не тестировал, но, вероятно, np.copy уже отправляет правильно, если массив не является NumPy.

Должно, оформлено для поддержки __array_function__ .

Для ясности, вы также имеете в виду функцию np.array_like ? Я намеренно избегал такого имени, потому что думал, что оно может сбивать с толку все существующие ссылки на array_like-array.

Да. И да, согласен, это может сбивать с толку.

Однако теперь я понимаю, что np.copy_like может означать необходимую копию,

Да, это имя подразумевает копию данных.

может означать необходимую копию, и я думаю, было бы неплохо иметь поведение, подобное np.asarray ,

Я думал, что это np.duckarray .

Я думаю, что приведенный выше пример Питера может помочь прояснить это. Скопировано ниже и для простоты вложено в np.copy_like .

import numpy as np, cupy as cp
a  = cp.array([1, 2])
b = [1, 2]
c = np.copy_like(b, like=a)

Я думал, что это np.duckarray.

Фактически, np.duckarray основном ничего не будет делать и просто вернет сам массив (если переопределен), иначе вернет np.asarray (что приведет к массиву NumPy). Например, с его помощью мы не можем получить массив CuPy из списка Python. Нам все еще нужна функция, которая может быть отправлена ​​в CuPy (или любой другой массив like= ) для array_like .

Спасибо @jakirkham за обновленный пример.

c = np.copy_like(b, like=a)

Так что он будет отправлен в CuPy через a.__array_function__ и завершится ошибкой, если этот атрибут не существует (например, a=<scipy.sparse matrix> не будет работать)? Похоже, нам нужно новое пространство имен или новый пакет утилит взаимодействия для такого рода вещей. Либо это, либо оставьте это более полнофункциональному будущему механизму диспетчеризации, где можно было бы просто:

with cupy_backend:
   np.array(b)

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

Так что он будет отправлен в CuPy через a.__array_function__ и завершится ошибкой, если этот атрибут не существует (например, a=<scipy.sparse matrix> не будет работать)?

Я бы не сказал, что он обязательно должен потерпеть неудачу. Например, мы могли бы по умолчанию использовать NumPy и выдавать предупреждение (или не выдавать его вообще).

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

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

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

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

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

На самом деле, в этом смысле np.duckarray также не принадлежит основному пространству имен.

На самом деле, в этом смысле np.duckarray также не принадлежит основному пространству имен.

Я думаю, что это более оправданно (аналог asarray и он в основном проверяет, "соответствует ли это нашему определению типа утки, подобного ndarray"), но да. Если мы также хотим раскрыть array_function_dispatch , и у нас есть вещи np.lib.mixins.NDArrayOperatorsMixin и мы планируем писать больше миксинов, разумный новый подмодуль для всех вещей, связанных с взаимодействием, может иметь смысл.

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

Я думаю, есть несколько причин. __array_function__ похож на то, что у нас уже было, поэтому его легче рассуждать. У него низкие накладные расходы. Его можно было разработать и реализовать в течение ~ 6 месяцев, и @shoyer убедительно доказал, что нам это нужно. И у нас не было конкретной альтернативы.

разумный новый подмодуль для всех вещей, связанных с совместимостью, может иметь смысл.

Никаких возражений с моей стороны, я считаю, что лучше где-то иметь функционал, чем нигде. :)

Я думаю, есть несколько причин. __array_function__ похож на то, что у нас уже было, поэтому его легче рассуждать. У него низкие накладные расходы. Его можно было разработать и реализовать в течение ~ 6 месяцев, и @shoyer убедительно доказал, что нам это нужно. И у нас не было конкретной альтернативы.

Но если мы хотим использовать __array_function__ более широком смысле, есть ли у нас сейчас другие альтернативы реализации таких вещей, как np.duckarray и np.copy_like (или как еще мы решили бы это назвать)? Я открыт для всех альтернатив, но сейчас я их, конечно, не вижу, вместо того, чтобы использовать полнофункциональный способ диспетчеризации, который, вероятно, займет много времени и ограничит объем __array_function__ невероятно (и в основном это делает его непрактичным для большинства более сложных случаев, которые я видел).

Но если мы хотим использовать __array_function__ более широком смысле, есть ли у нас сейчас другие альтернативы реализации таких вещей, как np.duckarray и np.copy_like (или как еще мы решили бы это назвать)?

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

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

Я имею в виду, мы просто затыкаем здесь несколько очевидных дыр, верно? Мы никогда не собираемся рассматривать все «более сложные случаи». Допустим, вы хотите переопределить np.errstate или np.dtype , но этого просто не произойдет с подходом на основе протокола.

Что касается альтернатив, uarray еще не существует, и я еще не уверен, что накладные расходы будут уменьшены до достаточно низкого уровня, чтобы их можно было использовать по умолчанию в NumPy, но он приближается, и мы собираемся попробовать его для создания scipy.fft Бэкэнд-система за https://github.com/Quansight-Labs/uarray/tree/master/unumpy

Диспетчерский подход с uarray, безусловно, интересен. Хотя меня все еще беспокоит, как мы обрабатываем мета-массивы (например, Dask, xarray и т. Д.). Пожалуйста, смотрите этот комментарий для деталей. Непонятно, как к этому обращались (хотя, пожалуйста, поправьте меня, если я что-то пропустил). Мне было бы интересно поработать с другими в SciPy, чтобы попытаться выяснить, как мы решаем эту проблему.

Пожалуйста, смотрите этот комментарий для деталей. Непонятно, как к этому обращались (хотя, пожалуйста, поправьте меня, если я что-то пропустил).

Я думаю, что изменения, внесенные на прошлой неделе, решат это, но не уверен - оставим это для другой темы.

Мне было бы интересно поработать с другими в SciPy, чтобы попытаться выяснить, как мы решаем эту проблему.

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

Возможно, имена np.coerce_like() или np.cast_like() будут лучше, чем copy_like , так что ясно, что копии не обязательно требуются. Желаемая функциональность действительно очень похожа на метод .cast() , за исключением того, что мы хотим преобразовать типы массивов, а также dtypes, и это должна быть функция, а не протокол, чтобы ее можно было реализовать любым аргументом.

Диспетчерский подход с uarray, безусловно, интересен. Хотя меня все еще беспокоит, как мы обрабатываем мета-массивы (например, Dask, xarray и т. Д.).

uarray поддерживает несколько бэкэндов, так что что-то вроде этого должно работать

with ua.set_backend(inner_array_backend), ua.set_backend(outer_array_backend):
  s = unumpy.sum(meta_array)

Это можно сделать, если вызов мета-массива ua.skip_backend внутри его реализации, или если бэкэнд мета-массива возвращает NotImplemented при несоответствии типа.

Копия: @hameerabbasi

Я подробно остановлюсь на этом: как правило, для dask.array все, что имеет da , будет записано без skip_backend. Все, что связано с NumPy, потребует skip_backend.

Или для da вы всегда можете пропустить отправку и вызвать свою собственную реализацию напрямую и везде иметь skip_backend(dask.array) .

Что касается диспетчерских функций, к которым не прикреплен массив, например ones , cast , вы просто установите бэкэнд и все готово. То же самое для np.errstate и np.dtype . Вот пример, покрывающий np.ufunc в unumpy .

Что касается исходной проблемы, uarray предоставляет протокол __ua_convert__ , который делает именно это. В качестве альтернативы серверная часть могла бы напрямую переопределить asarray .

Спасибо за внимание к uarray , @rgommers , @ peterbell10 , @hameerabbasi.

Но, как я вижу, вы _должны_ установить правильный бэкэнд перед запуском вычислений, это правильно? Одно из преимуществ __array_function__ заключается в том, что библиотеки могут быть полностью независимыми от других библиотек, например, Dask не должен знать о существовании CuPy.

@pentschev Так было до недавнего времени, когда мы добавили возможность «регистрировать» серверную часть, но мы рекомендуем только NumPy (или эталонную реализацию) делать это. Тогда пользователям, использующим Dask, понадобится всего один set_backend.

Понятно , я думаю, это то, что https://github.com/numpy/numpy/issues/13831#issuecomment -507432311, указывая на бэкэнды в https://github.com/Quansight-Labs/uarray / tree / master / unumpy.

Извините за так много вопросов, но что, если какое-то гипотетическое приложение полагается на различные бэкенды, например, как NumPy, так и Sparse, где в зависимости от ввода пользователя, возможно, все будет только NumPy, только Sparse или их сочетание. @ peterbell10 упомянул, что поддерживается несколько бэкэндов https://github.com/numpy/numpy/issues/13831#issuecomment -507458331, но можно ли сделать выбор бэкэнда автоматическим или возникнет необходимость обрабатывать три случая отдельно?

Итак, в этом случае вы в идеале должны зарегистрировать NumPy, использовать диспетчер контекста для Sparse и вернуть NotImplemented из sparse, когда это необходимо, что заставит что-то вернуться к NumPy.

В SciPy @rgommers , @danielballan и я говорили об этой проблеме. Мы пришли к выводу, что было бы полезно продолжить добавление duckarray (используя это имя). Тем не менее, похоже, что это будет версия 1.18. Хотя, пожалуйста, поправьте меня, если я что-то не понял. Учитывая это, можно было бы начать пиар?

Мы пришли к выводу, что было бы полезно продолжить добавление duckarray (используя это имя). Тем не менее, похоже, что это будет версия 1.18. Хотя, пожалуйста, поправьте меня, если я что-то не понял. Учитывая это, можно было бы начать пиар?

Для меня все это звучит здорово, но было бы хорошо начать с короткого нэпа, в котором изложено точное предложение. См. Https://github.com/numpy/numpy/issues/13831#issuecomment -507334210

Конечно, в этом есть смысл. 🙂

Что касается точки копирования, о которой говорилось ранее, мне любопытно, не решена ли она с помощью существующих механизмов. В частности, что насчет этих строк?

a2 = np.empty_like(a1)
a2[...] = a1[...]

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

Мы пришли к выводу, что было бы полезно продолжить добавление duckarray (используя это имя).

Для меня все это звучит здорово, но было бы хорошо начать с короткого нэпа, в котором изложено точное предложение. См. # 13831 (комментарий)

Я уже начал писать это, но пока не смог его завершить (извините за плохое планирование https://github.com/numpy/numpy/issues/13831#issuecomment-507336302).

Что касается точки копирования, о которой говорилось ранее, мне любопытно, не решена ли она с помощью существующих механизмов. В частности, что насчет этих строк?

a2 = np.empty_like(a1)
a2[...] = a1[...]

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

Вы можете это сделать, но для этого может потребоваться особая логика копирования (например, в CuPy https://github.com/cupy/cupy/pull/2079).

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

С другой стороны, это была бы своего рода замена asarray . Поэтому мне было интересно, если бы вместо какой-то функции copy_like new мы хотели бы вернуться к идее, предложенной NEP-18 :

Им потребуются собственные протоколы:
...
array и asarray, поскольку они явно предназначены для принуждения к фактическому объекту numpy.ndarray.

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

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

На встрече разработчиков и спринте на SciPy'19 был достигнут консенсус: давайте выпустим 1.17.0 и получим некоторый реальный опыт работы с ней, прежде чем предпринимать какие-либо следующие шаги.

на самом деле просто интересно, стоит ли нам вернуться к этой идее и обсудить.

наверное да, но через несколько месяцев.

наверное да, но через несколько месяцев.

Хорошо, спасибо за ответ!

Что касается точки копирования, о которой говорилось ранее, мне любопытно, не решена ли она с помощью существующих механизмов. В частности, что насчет этих строк?

a2 = np.empty_like(a1)
a2[...] = a1[...]

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

Моя основная проблема в том, что это не сработает для неизменяемых массивов уток, что не так уж редко. Кроме того, для NumPy дополнительные затраты на выделение массива и последующее его заполнение могут быть почти нулевыми, но я не уверен, что это верно для всех массивов уток.

Что касается точки копирования, о которой говорилось ранее, мне любопытно, не решена ли она с помощью существующих механизмов. В частности, что насчет этих строк?

a2 = np.empty_like(a1)
a2[...] = a1[...]

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

Вы можете это сделать, но для этого может потребоваться особая логика копирования (например, в CuPy cupy / cupy # 2079 ).

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

С другой стороны, это была бы своего рода замена asarray . Поэтому мне было интересно, если бы вместо какой-то функции copy_like new мы хотели бы вернуться к идее, предложенной NEP-18 :

Им потребуются собственные протоколы:
...
array и asarray, поскольку они явно предназначены для принуждения к фактическому объекту numpy.ndarray.

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

Я не думаю, что это хорошая идея менять поведение np.array или np.asarray с новым протоколом. Их установленное значение - преобразование в массивы NumPy, поэтому нам и нужно np.duckarray

Тем не менее, мы могли бы рассмотреть возможность добавления аргумента like к duckarray . Это потребует изменения протокола из упрощенного предложения выше - возможно, использовать __array_function__ вместо специального протокола, такого как __duckarray__ ? Я действительно не думал об этом.

Что касается точки копирования, о которой говорилось ранее, мне любопытно, не решена ли она с помощью существующих механизмов. В частности, что насчет этих строк?

a2 = np.empty_like(a1)
a2[...] = a1[...]

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

Моя основная проблема в том, что это не сработает для неизменяемых массивов уток, что не так уж редко. Кроме того, для NumPy дополнительные затраты на выделение массива и последующее его заполнение могут быть почти нулевыми, но я не уверен, что это верно для всех массивов уток.

Это честно. На самом деле мы уже можем кое-что упростить. Например, сегодня это работает с CuPy и Sparse.

a2 = np.copy(a1)

Это честно. На самом деле мы уже можем кое-что упростить. Например, сегодня это работает с CuPy и Sparse.

a2 = np.copy(a1)

Да, но мы также хотим «скопировать этот массив уток в тип этого другого массива уток»

Я не думаю, что это хорошая идея менять поведение np.array или np.asarray с новым протоколом. Их установленное значение - преобразование в массивы NumPy, поэтому нам и нужно np.duckarray

Я тоже не уверен в этом, и я не хотел даже поднимать этот вопрос, поэтому я не делал этого до сегодняшнего дня.

Тем не менее, мы могли бы рассмотреть возможность добавления подобного аргумента в duckarray. Для этого потребуется изменить протокол из упрощенного предложения выше - возможно, использовать __array_function__ вместо специального протокола, такого как __duckarray__? Я действительно не думал об этом.

Я не знаю, возникнут ли с этим какие-либо осложнения, хотя нам, вероятно, нужно немного осторожности, но мне нравится эта идея. Это могло бы показаться излишним на разных уровнях, но, возможно, чтобы следовать существующему шаблону, вместо добавления параметра like мы могли бы иметь duckarray и duckarray_like ?

Да, но мы также хотим «скопировать этот массив уток в тип этого другого массива уток»

Как насчет того, чтобы основывать это на np.copyto ?

Как насчет того, чтобы основывать это на np.copyto ?

Не стесняйтесь поправлять меня, если я ошибаюсь, но я предполагаю, что вы имеете в виду что-то вроде:

np.copyto(cupy_array, numpy_array)

Это может сработать, если NumPy хочет изменить текущее поведение, например, asarray всегда подразумевает, что местом назначения является массив NumPy, делает ли copyto такое же предположение?

np.copyto уже поддерживает отправку с помощью __array_function__ , но это примерно эквивалентно:

def copyto(dst, src):
    dst[...] = src

Нам нужен эквивалент:

def copylike(src, like):
    dst = np.empty_like(like)
    dst[...] = src
    return dst

np.copyto уже поддерживает отправку с помощью __array_function__ , но это примерно эквивалентно:

def copyto(dst, src):
    dst[...] = src

Нам нужен эквивалент:

def copylike(src, like):
    dst = np.empty_like(like)
    dst[...] = src
    return dst

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

Что ж, copyto может иметь смысл в зависимости от того, как мы об этом думаем. Возьмем, к примеру, следующий вариант использования.

np.copyto(cp.ndarray, np.random.random((3,)))

Это может быть преобразовано во что-то вроде выделения и копирования данных, как мы уже обсуждали. Если мы отправим около dst (в данном случае cp.ndarray ), то библиотеки с неизменяемыми массивами также могут реализовать это подходящим образом. Это также избавляет нас от добавления нового API (который NumPy просто предоставляет, но не использует), что казалось проблемой.

Чтобы вывести на поверхность еще одну мысль, которая недавно пришла мне в голову, стоит подумать о том, что эти API-интерфейсы будут означать в дальнейшем между другими библиотеками (например, как взаимодействуют Dask и Xarray).

Была ли эта страница полезной?
0 / 5 - 0 рейтинги