Связь между scipy и numpy

scipy представляется, обеспечивает большинство (но не всех [1]) функций numpy в своем собственном пространстве имен. Другими словами, если есть функция с именем numpy.foo , почти наверняка будет scipy.foo . В большинстве случаев они кажутся точно такими же, часто даже указывающими на один и тот же функциональный объект.

Иногда они разные. Чтобы привести пример, который появился недавно:

  • numpy.log10 – это ufunc, который возвращает NaN для отрицательных аргументов;
  • scipy.log10 возвращает комплексные значения для отрицательных аргументов и не представляется ufunc.

То же самое можно сказать и о log , log2 и log2 , но не о log1p [2].

С другой стороны, numpy.exp и scipy.exp кажутся разными именами для одного и того же ufunc. Это также относится к scipy.log1p и numpy.log1p .

Другим примером является numpy.linalg.solve vs scipy.linalg.solve . Они похожи, но последний предлагает некоторые дополнительные функции над первым.

Почему очевидное дублирование? Если это предназначено для оптового импорта numpy в scipy namespace, почему тонкие различия в поведении и недостающие функции? Есть ли какая-то всеобъемлющая логика, которая поможет устранить путаницу?

[1] numpy.min , numpy.max , numpy.abs и некоторые другие не имеют аналогов в пространстве имен scipy .

[2] Протестировано с использованием numpy 1.5.1 и scipy 0.9.0rc2.

  • Ускорение вложенных циклов с усилением элементов
  • Понимание наименее квадратной функции scipy с IRLS
  • поиск ближайших элементов в двух списках / массивах в Python
  • Как получить плоскую кластеризацию, соответствующую цветным кластерам в дендрограмме, созданной scipy
  • Пример python scipy.odrpack.odr (с образцом ввода / вывода)?
  • Ошибка загрузки PYTHON DLL
  • Как ограничить ширину окна корреляции в Numpy?
  • Перевести код matlab на python (scipy)
  • 8 Solutions collect form web for “Связь между scipy и numpy”

    В прошлый раз, когда я проверил его, метод scipy __init__ выполняет

     from numpy import * 

    так что все пространство имен numpy включено в scipy, когда импортируется модуль scipy.

    log10 поведение log10 интересно, потому что обе версии идут от numpy. Один из них – ufunc , другой – функция numpy.lib . Почему scipy предпочитает библиотечную функцию над ufunc , я не знаю, с моей точки зрения.


    EDIT: На самом деле, я могу ответить на вопрос log10 . Глядя в метод scipy __init__ я вижу следующее:

     # Import numpy symbols to scipy name space import numpy as _num from numpy import oldnumeric from numpy import * from numpy.random import rand, randn from numpy.fft import fft, ifft from numpy.lib.scimath import * 

    Функция log10 вы получаете в scipy, поступает из numpy.lib.scimath . Глядя на этот код, он говорит:

     """ Wrapper functions to more user-friendly calling of certain math functions whose output data-type is different than the input data-type in certain domains of the input. For example, for functions like log() with branch cuts, the versions in this module provide the mathematically valid answers in the complex plane: >>> import math >>> from numpy.lib import scimath >>> scimath.log(-math.exp(1)) == (1+1j*math.pi) True Similarly, sqrt(), other base logarithms, power() and trig functions are correctly handled. See their respective docstrings for specific examples. """ 

    Кажется, что модуль накладывает базовые numpy ufuncs для sqrt , log , log2 , log2 , log10 , power , arccos , arcsin и arctanh . Это объясняет поведение, которое вы видите. Основная причина, по которой это делается, вероятно, похожа на место в почтовом списке.

    Из справочного руководства SciPy:

    … все функции Numpy были scipy пространство имен scipy чтобы все эти функции были доступны без дополнительного импорта Numpy.

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

    Из scipy часто задается вопросом, что некоторые функции из numpy здесь по историческим причинам, в то время как это должно быть только в scipy:

    В чем разница между NumPy и SciPy?

    В идеальном мире NumPy будет содержать только тип данных массива и самые основные операции: индексирование, сортировка, переформатирование, основные элементарные функции и т. Д. Весь цифровой код будет находиться в SciPy. Однако одной из важных целей NumPy является совместимость, поэтому NumPy пытается сохранить все функции, поддерживаемые одним из своих предшественников. Таким образом, NumPy содержит некоторые функции линейной алгебры, хотя они более правильно принадлежат SciPy. В любом случае SciPy содержит более полнофункциональные версии модулей линейной алгебры, а также многие другие численные алгоритмы. Если вы занимаетесь научными вычислениями с помощью python, вы должны установить как NumPy, так и SciPy. Большинство новых функций принадлежат SciPy, а не NumPy.

    Это объясняет, почему scipy.linalg.solve предлагает некоторые дополнительные функции над numpy.linalg.solve .

    РЕДАКТИРОВАТЬ:

    Я не видел ответа SethMMorton на соответствующий вопрос

    В конце введения в документацию SciPy есть короткий комментарий:

    Другая полезная команда – source . Когда задана функция, написанная на Python в качестве аргумента, она выводит список исходного кода для этой функции. Это может быть полезно при изучении алгоритма или в понимании того, что функция выполняет с его аргументами. Также не забывайте о директории команды Python, которая может использоваться для просмотра пространства имен модуля или пакета.

    Я думаю, что это позволит кому-то, у кого достаточно знаний обо всех пакетах, разобрать, какие именно различия между некоторыми функциями scipy и numpy (это не помогло мне с вопросом log10 вообще). У меня определенно нет этих знаний, но source указывает, что scipy.linalg.solve и numpy.linalg.solve взаимодействуют с лапкой по-разному;

     Python 2.4.3 (#1, May 5 2011, 18:44:23) [GCC 4.1.2 20080704 (Red Hat 4.1.2-50)] on linux2 >>> import scipy >>> import scipy.linalg >>> import numpy >>> scipy.source(scipy.linalg.solve) In file: /usr/lib64/python2.4/site-packages/scipy/linalg/basic.py def solve(a, b, sym_pos=0, lower=0, overwrite_a=0, overwrite_b=0, debug = 0): """ solve(a, b, sym_pos=0, lower=0, overwrite_a=0, overwrite_b=0) -> x Solve a linear system of equations a * x = b for x. Inputs: a -- An N x N matrix. b -- An N x nrhs matrix or N vector. sym_pos -- Assume a is symmetric and positive definite. lower -- Assume a is lower triangular, otherwise upper one. Only used if sym_pos is true. overwrite_y - Discard data in y, where y is a or b. Outputs: x -- The solution to the system a * x = b """ a1, b1 = map(asarray_chkfinite,(a,b)) if len(a1.shape) != 2 or a1.shape[0] != a1.shape[1]: raise ValueError, 'expected square matrix' if a1.shape[0] != b1.shape[0]: raise ValueError, 'incompatible dimensions' overwrite_a = overwrite_a or (a1 is not a and not hasattr(a,'__array__')) overwrite_b = overwrite_b or (b1 is not b and not hasattr(b,'__array__')) if debug: print 'solve:overwrite_a=',overwrite_a print 'solve:overwrite_b=',overwrite_b if sym_pos: posv, = get_lapack_funcs(('posv',),(a1,b1)) c,x,info = posv(a1,b1, lower = lower, overwrite_a=overwrite_a, overwrite_b=overwrite_b) else: gesv, = get_lapack_funcs(('gesv',),(a1,b1)) lu,piv,x,info = gesv(a1,b1, overwrite_a=overwrite_a, overwrite_b=overwrite_b) if info==0: return x if info>0: raise LinAlgError, "singular matrix" raise ValueError,\ 'illegal value in %-th argument of internal gesv|posv'%(-info) >>> scipy.source(numpy.linalg.solve) In file: /usr/lib64/python2.4/site-packages/numpy/linalg/linalg.py def solve(a, b): """ Solve the equation ``ax = b`` for ``x``. Parameters ---------- a : array_like, shape (M, M) Input equation coefficients. b : array_like, shape (M,) Equation target values. Returns ------- x : array, shape (M,) Raises ------ LinAlgError If `a` is singular or not square. Examples -------- Solve the system of equations ``3 * x0 + x1 = 9`` and ``x0 + 2 * x1 = 8``: >>> a = np.array([[3,1], [1,2]]) >>> b = np.array([9,8]) >>> x = np.linalg.solve(a, b) >>> x array([ 2., 3.]) Check that the solution is correct: >>> (np.dot(a, x) == b).all() True """ a, _ = _makearray(a) b, wrap = _makearray(b) one_eq = len(b.shape) == 1 if one_eq: b = b[:, newaxis] _assertRank2(a, b) _assertSquareness(a) n_eq = a.shape[0] n_rhs = b.shape[1] if n_eq != b.shape[0]: raise LinAlgError, 'Incompatible dimensions' t, result_t = _commonType(a, b) # lapack_routine = _findLapackRoutine('gesv', t) if isComplexType(t): lapack_routine = lapack_lite.zgesv else: lapack_routine = lapack_lite.dgesv a, b = _fastCopyAndTranspose(t, a, b) pivots = zeros(n_eq, fortran_int) results = lapack_routine(n_eq, n_rhs, a, n_eq, pivots, b, n_eq, 0) if results['info'] > 0: raise LinAlgError, 'Singular matrix' if one_eq: return wrap(b.ravel().astype(result_t)) else: return wrap(b.transpose().astype(result_t)) 

    Это также мой первый пост, поэтому, если мне что-то изменить, пожалуйста, дайте мне знать.

    Материал из Википедии ( http://ru.wikipedia.org/wiki/NumPy#History ):

    Цифровой код был адаптирован, чтобы сделать его более удобным и гибким для реализации новых функций Numarray. Этот новый проект был частью SciPy. Чтобы избежать установки целого пакета только для получения объекта массива, этот новый пакет был разделен и назывался NumPy.

    scipy зависит от numpy и импортирует множество функций numpy в пространство имен для удобства.

    Что касается пакета linalg – функции scipy будут вызывать lapack и blas, которые доступны в высоко оптимизированных версиях на многих платформах и обеспечивают очень хорошую производительность, особенно для операций на достаточно больших плотных матрицах. С другой стороны, им нелегко собирать библиотеки для компиляции, требуя компилятора fortran и многих теневых настроек платформы, чтобы получить полную производительность. Поэтому numpy обеспечивает простые реализации многих общих функций линейной алгебры, которые часто достаточно хороши для многих целей.

    В дополнение к часто задаваемым параметрам SciPy, описывающим дублирование, в основном для обратной совместимости, в документах NumPy далее разъясняется, что

    Необязательно ускоренные подпрограммы (numpy.dual)

    Псевдонимы для функций, которые могут ускоряться Scipy.

    Scipy может быть построен для использования ускоренных или улучшенных библиотек для БПФ, линейной алгебры и специальных функций. Этот модуль позволяет разработчикам прозрачно поддерживать эти ускоренные функции, когда scipy доступен, но по-прежнему поддерживает пользователей, которые только установили Numpy.

    Для краткости это:

    • Линейная алгебра
    • FFT
    • Модифицированная функция Бесселя первого рода, порядок 0

    Кроме того, из учебника SciPy :

    Верхний уровень scipy также содержит функции от numpy и numpy.lib.scimath. Однако лучше использовать их непосредственно из модуля numpy.

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

    В моем личном опыте большинство функций массива, которые я использую, существуют на верхнем уровне NumPy (кроме random ). Тем не менее, все подпрограммы, относящиеся к домену, существуют в подпакетах SciPy, поэтому я редко использую что-либо из верхнего уровня SciPy.

    Из лекций « Количественная экономика »

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

    Фактически, когда мы импортируем SciPy, мы также получаем NumPy, как видно из файла инициализации SciPy

     # Import numpy symbols to scipy name space import numpy as _num linalg = None from numpy import * from numpy.random import rand, randn from numpy.fft import fft, ifft from numpy.lib.scimath import * __all__ = [] __all__ += _num.__all__ __all__ += ['randn', 'rand', 'fft', 'ifft'] del _num # Remove the linalg imported from numpy so that the scipy.linalg package can be # imported. del linalg __all__.remove('linalg') 

    Тем не менее, более распространенной и лучшей практикой является использование функций NumPy явно

     import numpy as np a = np.identity(3) 

    Что полезно в SciPy – это функциональность в своих подпакетах

    • scipy.optimize, scipy.integrate, scipy.stats и т. д.
    Python - лучший язык программирования в мире.