online datos con cientifico ciencia python numpy scipy

python - con - ciencia de datos online



Relación entre ciencia y número (8)

SciPy parece proporcionar la mayoría (pero no todas [1]) de las funciones de NumPy en su propio espacio de nombres. En otras palabras, si hay una función llamada numpy.foo , es casi seguro que hay un scipy.foo . La mayoría de las veces, los dos parecen ser exactamente iguales, a menudo incluso apuntando al mismo objeto de función.

A veces, son diferentes. Para dar un ejemplo que surgió recientemente:

  • numpy.log10 es un ufunc que devuelve NaNs para argumentos negativos;
  • scipy.log10 devuelve valores complejos para argumentos negativos y no parece ser un ufunc.

Lo mismo se puede decir sobre log , log2 y logn , pero no sobre log1p [2].

Por otro lado, numpy.exp y scipy.exp parecen ser nombres diferentes para el mismo ufunc. Esto también es válido para scipy.log1p y numpy.log1p .

Otro ejemplo es numpy.linalg.solve vs scipy.linalg.solve . Son similares, pero el último ofrece algunas características adicionales sobre el primero.

¿Por qué la aparente duplicación? Si se pretende que esto sea una importación al por mayor de numpy al espacio de nombres scipy , ¿por qué las diferencias sutiles en el comportamiento y las funciones faltantes? ¿Hay alguna lógica general que ayude a aclarar la confusión?

[1] numpy.min , numpy.max , numpy.abs y algunos otros no tienen equivalentes en el espacio de nombres scipy .

[2] Probado usando NumPy 1.5.1 y SciPy 0.9.0rc2.


Además de las Preguntas Frecuentes de SciPy que describen la duplicación es principalmente para la compatibilidad con versiones anteriores, se aclara más en la documentación de NumPy para decir que

Opcionalmente rutinas aceleradas por SciPy (numpy.dual)

Alias ​​para funciones que pueden ser aceleradas por Scipy.

SciPy puede construirse para usar bibliotecas aceleradas o mejoradas de otro modo para FFT, álgebra lineal y funciones especiales. Este módulo permite a los desarrolladores admitir estas funciones aceleradas de forma transparente cuando SciPy está disponible, pero aún así admite usuarios que solo han instalado NumPy.

Por brevedad, estos son:

  • Álgebra lineal
  • FFT
  • La función Bessel Modificada del primer tipo, orden 0

Además, desde el Tutorial de SciPy :

El nivel superior de SciPy también contiene funciones de NumPy y numpy.lib.scimath. Sin embargo, es mejor utilizarlos directamente desde el módulo NumPy.

Por lo tanto, para las nuevas aplicaciones, debería preferir la versión NumPy de las operaciones de matriz que están duplicadas en el nivel superior de SciPy. Para los dominios mencionados anteriormente, debería preferir los de SciPy y verificar la compatibilidad con versiones anteriores si es necesario en NumPy.

En mi experiencia personal, la mayoría de las funciones de matriz que uso existen en el nivel superior de NumPy (excepto random ). Sin embargo, todas las rutinas específicas del dominio existen en subpaquetes de SciPy, por lo que rara vez uso algo del nivel superior de SciPy.


Con respecto al paquete linalg: las funciones scipy se denominarán lapack y blas, que están disponibles en versiones altamente optimizadas en muchas plataformas y ofrecen un rendimiento muy bueno, en particular para operaciones en matrices densamente razonables. Por otro lado, no son bibliotecas fáciles de compilar, ya que requieren un compilador fortran y muchos ajustes específicos de la plataforma para obtener el máximo rendimiento. Por lo tanto, numpy proporciona implementaciones simples de muchas funciones comunes de álgebra lineal que a menudo son lo suficientemente buenas para muchos propósitos.


De Wikipedia ( http://en.wikipedia.org/wiki/NumPy#History ):

El código numérico se adaptó para que sea más fácil de mantener y lo suficientemente flexible como para implementar las características novedosas de Numarray. Este nuevo proyecto fue parte de SciPy. Para evitar instalar un paquete completo solo para obtener un objeto de matriz, este nuevo paquete se separó y se llamó NumPy.

scipy depende del numpy e importa muchas funciones de número en su espacio de nombres para su comodidad.


De la Guía de referencia SciPy:

... todas las funciones de Numpy se han incluido en el espacio de nombres scipy para que todas esas funciones estén disponibles sin importar adicionalmente Numpy.

La intención es que los usuarios no tengan que saber la distinción entre los numpy nombres scipy y numpy , aunque aparentemente haya encontrado una excepción.


De las Preguntas Frecuentes de SciPy parece que algunas funciones de NumPy están aquí por razones históricas, mientras que solo deberían estar en SciPy:

¿Cuál es la diferencia entre NumPy y SciPy?

En un mundo ideal, NumPy no contendría nada más que el tipo de datos de matriz y las operaciones más básicas: indexación, clasificación, remodelación, funciones elementales elementales, etc. Todo código numérico residiría en SciPy. Sin embargo, uno de los objetivos importantes de NumPy es la compatibilidad, por lo que NumPy trata de conservar todas las funciones compatibles con cualquiera de sus predecesores. Por lo tanto, NumPy contiene algunas funciones de álgebra lineal, aunque estas pertenecen más apropiadamente a SciPy. En cualquier caso, SciPy contiene más versiones completas de los módulos de álgebra lineal, así como muchos otros algoritmos numéricos. Si está haciendo informática científica con python, probablemente debería instalar tanto NumPy como SciPy. La mayoría de las características nuevas pertenecen a SciPy en lugar de NumPy.

Eso explica por qué scipy.linalg.solve ofrece algunas características adicionales sobre numpy.linalg.solve .

No vi la respuesta de SethMMorton a la pregunta relacionada


De las conferencias sobre '' Economía Cuantitativa ''

SciPy es un paquete que contiene varias herramientas que se construyen sobre NumPy, utilizando su tipo de datos de matriz y funcionalidad relacionada

De hecho, cuando importamos SciPy también obtenemos NumPy, como se puede ver en el archivo de inicialización de 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'')

Sin embargo, es más común y mejor práctica usar la funcionalidad NumPy explícitamente

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

Lo que es útil en SciPy es la funcionalidad en sus subpaquetes.

  • scipy.optimize, scipy.integrate, scipy.stats, etc.

Hay un breve comentario al final de la introducción a la documentación de SciPy :

Otro comando útil es la source . Cuando se le asigna una función escrita en Python como argumento, imprime una lista del código fuente para esa función. Esto puede ser útil para aprender sobre un algoritmo o para entender exactamente qué está haciendo una función con sus argumentos. Además, no olvide el directorio de comandos de Python, que se puede usar para ver el espacio de nombres de un módulo o paquete.

Creo que esto le permitirá a alguien con suficiente conocimiento de todos los paquetes involucrados distinguir exactamente cuáles son las diferencias entre algunas funciones scipy y numpy (no me ayudó en absoluto con la pregunta log10). Definitivamente no tengo ese conocimiento pero la source indica que scipy.linalg.solve y numpy.linalg.solve interactúan con lapack de diferentes maneras;

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 ``a x = 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))

Esta es también mi primera publicación, así que si debo cambiar algo aquí, por favor hágamelo saber.


La última vez que lo revisé, el método __init__ de __init__ ejecuta un

from numpy import *

de modo que todo el espacio de nombres numpy se incluye en scipy cuando se importa el módulo scipy.

El comportamiento de log10 que está describiendo es interesante, porque ambas versiones provienen de numpy. Uno es ufunc , el otro es una función numpy.lib . ¿Por qué scipy es preferir la función de biblioteca en lugar de ufunc , no sé de la cabeza.

EDIT: De hecho, puedo responder a la pregunta log10 . Mirando en el método __init__ de __init__ veo esto:

# 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 *

La función log10 que obtienes en scipy proviene de numpy.lib.scimath . Mirando ese código, dice:

""" 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. """

Parece que el módulo superpone el número base de ufuncs para sqrt , log , log2 , logn , log10 , power , arccos , arcsin y arctanh . Eso explica el comportamiento que estás viendo. La razón de diseño subyacente por la que se hace así probablemente está enterrada en una publicación de la lista de correo en algún lugar.