eficiencia de numpy.array
Francesc Altet
faltet en carabos.com
Jue Mar 8 20:12:58 CET 2007
El dj 08 de 03 del 2007 a les 19:15 +0100, en/na Chema Cortes va
escriure:
> El 8/03/07, Francesc Altet <faltet en carabos.com> escribió:
> > El dj 08 de 03 del 2007 a les 15:16 +0100, en/na Chema Cortes va
> > escriure:
> > > De todos modos, el numpy está pensado por y para matemáticos. Aunque
> > > no sea por "efectividad", deberías mirarlo desde el punto de vista
> > > matemático.
> >
> > Bueno, no estoy de acuerdo con eso de que numpy esté por y para
> > matemáticos, al menos en el sentido 'estricto' de matemático. Yo como
> > máximo diría que está hecho por 'calculistas' para 'calculistas'. Y sin
> > embargo, con esta última afirmación tampoco estaria haciendo del todo
> > justicia a NumPy.
>
> Totalmente de acuerdo, si por "calculista" se entiende lo que es un
> "NumberCruncher". Que numpy se emplea en más ámbitos que las
> matemáticas puras es clara muestra el que estamos hablándolo ahora
> mismo dos físicos :-D
Bueno, no sé si yo me puedo continuar llamando físico después de
abandonar el ramo hace ya casi veinte años, aunque para un informático
de carrera obsesionado con el 'intrusismo' laboral seguro que continúo
siendo un 'físico', lo cual no deja de ser un consuelo ;)
> > Aparte de los calculistas, numpy brilla con luz propia en otros aspectos
> > como por ejemplo como contenedores de datos complejos (que a posteriori
> > pueden ser usados en 'cálculos' tradicionales o no) con mucha eficiencia
> > o el tema de hacer ordenaciones a velocidades de C y con un consumo muy
> > eficiente de memoria.
>
> Aún así, desde que descubrí las "tablas" del lua no quiero otra cosa.
> Me gustaría que mucho que python tuviera ese grado de simpleza y toque
> "minimalista" que tiene lua; pero, en cambio, sólo veo interfaces cada
> vez más y más complejos, sin comprender con claridad las ventajas que
> puedan proporcionar.
Le tengo que echar un vistazo a lua. Un poco de promiscuidad de vez en
cuando (aunque sea en términos de lenguaje ;) no le viene mal a nadie.
> > Cuando digo contenedores 'complejos' me refiero al
> > hecho de que numpy no sólo es capaz de almacenar arrays homogéneos
> > (todos los componentes son del mismo tipo), sino también heterogéneos
> > (los componentes pueden ser de tipos diferentes, tipo tabla SQL) e
> > incluso heterogéneos con varios niveles de anidamiento. Esto es algo que
> > ya se empezó a introducir en numarray pero que se ha integrado y
> > mejorado sustancialmente en NumPy. Todo esto hace de NumPy una libreria
> > de uso yo diria que básico en bastantes campos diferentes de los de
> > 'calculismo'.
>
> No he visto cómo hacer estos contenedores heterogéneos. ¿Puedes poner
> algún ejemplo? (por ejemplo, mezclar float y complex).
Cómo no:
In [38]:dtype=numpy.dtype([('campo flotante', 'float64'), ('campo
complejo', 'complex128')])
In [39]:recarray = numpy.empty(3, dtype)
In [40]:recarray
Out[40]:
array([ (-3.0229727440451393e-39, (6.7512155807143104e-314
+7.6721912170850867e+218j)),
(2.87301221173249e+161, (1.9424519928790708e-313
+1.9297170390665241e-110j)),
(3.6490903000155174e+233, (3.275323060872541e-313
+3.6297756754403919e+228j))],
dtype=[('campo flotante', '<f8'), ('campo complejo', '<c16')])
In [41]:recarray['campo complejo']
Out[41]:
array([ 6.75121558e-314 +7.67219122e+218j,
1.94245199e-313 +1.92971704e-110j,
3.27532306e-313 +3.62977568e+228j])
In [42]:recarray['campo flotante']
Out[42]:array([ -3.02297274e-039, 2.87301221e+161, 3.64909030e+233])
Con campos anidados:
In [45]:recarray_anidado = numpy.empty(3, tipo_anidado)
In [46]:recarray_anidado
Out[46]:
array([(-2.8664755518548191e-05, -2.8664755518548191e-05, (0, 0)),
(4.7263799313282515e-34, -2.1512736566364765e-05, (91, 0)),
(5.330029341254113e-34, nan, (40, 0))],
dtype=[('x', '<f4'), ('y', '<f4'), ('nested', [('i', '<i2'), ('j',
'<i2')])])
In [47]:recarray_anidado['nested'] Out[47]:
array([(0, 0), (91, 0), (40, 0)],
dtype=[('i', '<i2'), ('j', '<i2')])
In [48]:recarray_anidado['nested']['i']
Out[48]:array([ 0, 91, 40], dtype=int16)
Puedes encontrar muchos otros ejemplos en:
http://www.scipy.org/Numpy_Example_List
> > > Los arrays del numpy aceptan tuplas como índices
> > > multidimensionales, así como el rebanado "extendido" ("extended
> > > slice"). Como ejemplo del primer caso (índices multidimensionales), una forma
> > > rápida de obtener todos los elementos de un array mayores de 100:
> >
> > Bueno, para ser exactos, habría que decir que Python implementa, desde
> > hace algunas versiones (2.3) el rebanado 'extendido', aunque sólo para
> > objetos unidimensionales, como se puede apreciar en:
> >
> > http://www.python.org/doc/2.3.5/whatsnew/section-slices.html
>
> En realidad, sólo se introdujo el "interface" de los slices. A parte
> de numpy, sólo está implementado en algún módulo que ahora no
> recuerdo. Pero, por defecto, no se pueden usar como índices otra cosa
> que números enteros.
Seguro?
In [49]:l = range(10)
In [50]:l
Out[50]:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [51]:l[2:6:3]
Out[51]:[2, 5]
> De hecho, en python 2.5 se ha tenido que
> introducir un nuevo interface (__index__) que necesitaba numpy para
> poder tener índices no enteros (eg: float).
Bueno, realmente la principal razón para introducir __index__ (de hecho
lo hizo el propio Travis Oliphant, el principal autor de NumPy) fue para
soportar escalares de NumPy. Un escalar de NumPy se obtiene al recuperar
un elemento sin dimensiones de un array. Por ejemplo:
In [56]:a=numpy.arange(10)
In [57]:scalar=a[1]
In [58]:scalar
Out[58]:1
In [59]:type(scalar)
Out[59]:<type 'numpy.int32'>
In [60]:isinstance(scalar, int)
Out[60]:True
Estos escalares, heredaban de los enteros python y se comportaban como
enteros a todos los efectos (con más características, pero esto no viene
al caso ahora). Sin embargo, Python no dejaba usar en los 'rebanados' a
objectos que no fueran enteros (o enteros largos) de raza 'pura'. La
solución que ideó Travis fue que los objectos que querian ser tratados
en pie de igualdad con los enteros de raza 'pura' habrian de declarar el
método especial __index__:
def __index__(self):
....
return obj
donde obj fuera un entero de raza 'pura'.
Realmente, el hecho de que ahora se permitan a los 'floats' actuar como
índices no estaba dentro de los deseos de Travis (de hecho, él lo
consideraba como 'undesirable behaviour'), aunque parece que finalmente
se ha hecho así (no sé las razones, la verdad).
> > > Pero hay mucho más, como el cálculo matricial, FFT, LinearAlgebra,...
> >
> > Correcto. Pero también hay que decir que existe una corriente ahora
> > mismo dentro de la comunidad de NumPy de empezar a mover parte del
> > código que se puede considerar estrictamente 'calculista' fuera de NumPy
> > para meterlo en SciPy. De esta manera se conseguiria un paquete muy
> > compacto (NumPy) que hace relativamente pocas cosas pero que las hace
> > muy bien y que, *muy importante*, sea fácil de instalar, y la parte más
> > complicada y más de cálculo en el sentido científico ponerla en SciPy,
> > cuyo tamaño es mucho mayor y *bastante* más difícil de instalar,
> > sobretodo si quiere obtener soporte de cálculo de muy altas prestaciones
> > (BLAS, LAPACK, etc.).
>
> Muy interesante. Esperemos que no se demore tanto como el libro de numpy ;-)
El libro de NumPy ya está a la venta desde hace más de un año!
http://www.tramy.us/guidetoscipy.html
:)
Saludos,
--
Francesc Altet | Be careful about using the following code --
Carabos Coop. V. | I've only proven that it works,
www.carabos.com | I haven't tested it. -- Donald Knuth
------------ próxima parte ------------
_______________________________________________
Python-es mailing list
Python-es en aditel.org
http://listas.aditel.org/listinfo/python-es
Más información sobre la lista de distribución Python-es