numpy.product против numpy.prod против ndarray.prod

Я читаю документы Numpy, и кажется, что функции np.prod(...), np.product(...) и метод ndarray a.prod(...) эквивалентны.

Есть ли предпочтительная версия для использования с точки зрения стиля/удобочитаемости и производительности? Существуют ли разные ситуации, когда разные версии предпочтительнее? Если нет, то почему существуют три разных, но очень похожих способа выполнения одной и той же операции?


person dkv    schedule 16.04.2018    source источник
comment
Это дзен NumPy. Должно быть три, а лучше больше трех неочевидных способов сделать это.   -  person wim    schedule 16.04.2018
comment
За исключением того, что если это псевдоним, они делают больше, чем просто переименовывают функцию. prod возвращает return _methods._prod(a, axis=axis, dtype=dtype, out=out, **kwargs), а product возвращает return um.multiply.reduce(a, axis=axis, dtype=dtype, out=out, **kwargs), но они оба находятся в модуле fromnumeric. Не так просто увидеть, как это эквивалентно...   -  person roganjosh    schedule 16.04.2018
comment
@roganjosh Я не понимаю ... в любом случае мне кажется, что umath.multiply.reduce в конечном итоге вызывается.   -  person miradulo    schedule 16.04.2018
comment
@miradulo да, я проследил за ним, и ты прав   -  person roganjosh    schedule 16.04.2018
comment
@miradulo на самом деле, похоже, это немного изменилось между моей пустой версией (1.13.1) и мастером. Теперь в источнике яснее, что это одно и то же, я сравнивал яблоки и апельсины в некотором смысле, глядя на источник в моем редакторе и в Интернете.   -  person roganjosh    schedule 16.04.2018
comment
Будьте осторожны, если производительность действительно важна. В зависимости от вашего варианта использования могут быть лучшие (а также простые в использовании) методы: stackoverflow.com/a/49321971/4045774   -  person max9111    schedule 16.04.2018


Ответы (2)


Что касается сегодняшней ветки master (1.15.0), np.product просто использует np.prod и в конечном итоге может быть объявлено устаревшим. См. ВНИМАНИЕ: удалите повторяющиеся реализации для функций с псевдонимами. №10653.

И np.prod, и ndarray.prod в конечном итоге вызывают umath.multiply.reduce, поэтому между ними нет никакой разницы, кроме того факта, что бесплатные функции могут принимать подобные типы (например, списки Python) в дополнение к массивам NumPy.

До этого, как и в NumPy 1.14.2, документация утверждала, что np.product и np.prod были одинаковыми, но были ошибки из-за дублированной реализации, о которой упоминает Parag. например, пример Эрика Вайзера из #10651:

>>> class CanProd(object):
        def prod(self, axis, dtype, out): return "prod"  
>>> np.product(CanProd())
<__main__.CanProd object at 0x0000023BAF7B29E8>
>>> np.prod(CanProd())
'prod'

Короче говоря, теперь они одинаковы и предпочитают np.prod np.product, поскольку последний является псевдонимом, который может быть объявлен устаревшим.

person miradulo    schedule 16.04.2018
comment
Есть что добавить; независимо от псевдонима обычно немного быстрее вызвать метод для объекта массива. arr = np.random.randint(1, 100, size=10000) --› timeit np.prod(arr) из 10.3 µs ± 27.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each). %timeit arr.prod() из 9.58 µs ± 18.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) - person roganjosh; 16.04.2018

Это то, что я смог почерпнуть из исходных кодов NumPy 1.14.0. Ответ, относящийся к текущей ветке Master (NumPy 1.15.0), см. в ответе miradulo.

  • Для ndarray prod() и product() эквивалентны.

  • Для ndarray, prod() и product() будут вызывать um.multiply.reduce().

  • Если тип объекта не ndarray, но у него все еще есть метод prod, то prod() вернет prod(axis=axis, dtype=dtype, out=out, **kwargs), тогда как product попытается использовать um.multiply.reduce.

  • Если объект не является ndarray и у него нет метода prod, он будет вести себя как product().

  • ndarray.prod() эквивалентно prod().

Я не уверен в последней части вашего вопроса о предпочтениях и удобочитаемости.

person Autonomous    schedule 16.04.2018