Ir al contenido principal

Tutorial de SciPy: vectores y arrays (álgebra lineal)

Un tutorial de SciPy en el que aprenderás los fundamentos de álgebra lineal que necesitas para machine learning en Python, con foco en el uso con NumPy.
Actualizado 17 sept 2026  · 15 min leer

Explorar con IA

ChatGPTClaudePerplexity

Gran parte de lo que necesitas para adentrarte de verdad en el machine learning es álgebra lineal, y justo eso es lo que aborda este tutorial. La publicación de hoy repasa los temas de álgebra lineal que debes conocer y comprender para mejorar tu intuición sobre cómo y cuándo funcionan los métodos de machine learning, bajando al nivel de vectores y matrices.

Al final del tutorial, esperamos que te sientas con más confianza para analizar un algoritmo de cerca.

Contenido


Introducción

Uno de los tres temas básicos que debes dominar si quieres aprender data science es el machine learning. Y cuando te metes de lleno en machine learning, es importante profundizar para adquirir intuición y entender cómo funcionan los algoritmos.

Y creo que tú, como (futuro) data scientist, probablemente estarás de acuerdo conmigo en que llegar a este punto puede ser todo un reto.

Pero no tiene por qué serlo.

SciPy frente a NumPy

En el tutorial de NumPy de DataCamp ya habrás visto que esta librería es una de las bases del cómputo científico en Python. Incluye un conjunto de herramientas y técnicas para resolver en el ordenador modelos matemáticos de problemas de ciencia e ingeniería. Pero la herramienta que más usarás es su objeto array multidimensional de alto rendimiento: una estructura de datos potente que te permite calcular arrays y matrices de forma eficiente.

Ahora bien, SciPy es, básicamente, NumPy.

También es uno de los paquetes clave para el cómputo científico y aporta algoritmos matemáticos y funciones de conveniencia, pero está construido sobre la extensión de NumPy para Python. Esto significa que SciPy y NumPy suelen utilizarse juntos.

Más adelante en este tutorial verás con claridad cómo la colaboración entre estas dos librerías es algo natural.

Interactuar con NumPy y SciPy

Para trabajar con ambos paquetes con soltura, primero necesitas conocer algunas bases de la librería y su potente estructura de datos. Para trabajar con estos arrays, tienes a tu disposición una enorme cantidad de funciones matemáticas de alto nivel que operan sobre matrices y arrays.

A continuación, verás un repaso rápido de los temas que debes dominar para trabajar de forma eficiente con SciPy. En esencia, tienes que conocer la estructura de los arrays, cómo manejar los tipos de datos y cómo manipular la forma de los arrays. Si esto te suena a chino, plantéate hacer el tutorial de NumPy en Python de DataCamp y, mientras aprendes, echa un vistazo a la chuleta de NumPy.

Si ya controlas todo esto, salta a la siguiente sección y ve a «Álgebra lineal con SciPy», pero ten a mano la chuleta de SciPy para álgebra lineal.

data science courses banner

Imprescindibles de los objetos ndarray de NumPy

Estructuralmente, un array no es más que punteros. Es la combinación de una dirección de memoria, un tipo de dato, una forma y unos saltos (strides). Contiene información sobre los datos en bruto, cómo localizar un elemento y cómo interpretarlo.

La dirección de memoria y los strides son importantes cuando profundizas en los detalles de bajo nivel de los arrays, mientras que el tipo de dato y la forma son cosas que quienes empiezan deberían conocer y entender. Otros dos atributos que quizá quieras considerar son data y size, que te permiten obtener aún más información sobre tu array.

Refresca el uso de los atributos de ndarray en el siguiente bloque de DataCamp Light. El array myArray ya se ha cargado. Puedes inspeccionarlo escribiéndolo en el shell de IPython y pulsando ENTER.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wXG5teUFycmF5ID0gbnAuYXJyYXkoW1sxLDIsM10sWzQsNSw2XV0pIiwic2FtcGxlIjoiIyBJbnNwZWN0IHRoZSBkYXRhIG9mIGBteUFycmF5YFxucHJpbnQobXlBcnJheS5kYXRhKVxuXG4jIEluc3BlY3QgdGhlIGRhdGEgdHlwZSBvZiBgbXlBcnJheWBcbnByaW50KF9fX19fX19fX19fX19fX19fKVxuXG4jIEluc3BlY3QgdGhlIHNoYXBlIG9mIGBteUFycmF5YFxucHJpbnQoX19fX19fX19fX19fX19fX19fKVxuXG4jIEluc3BlY3QgdGhlIHNpemUgb2YgYG15QXJyYXlgXG5wcmludChfX19fX19fX19fX19fX19fX18pIiwic29sdXRpb24iOiIjIEluc3BlY3QgdGhlIGRhdGEgb2YgYG15QXJyYXlgXG5wcmludChteUFycmF5LmRhdGEpXG5cbiMgSW5zcGVjdCB0aGUgZGF0YSB0eXBlIG9mIGBteUFycmF5YFxucHJpbnQobXlBcnJheS5kdHlwZSlcblxuIyBJbnNwZWN0IHRoZSBzaGFwZSBvZiBgbXlBcnJheWBcbnByaW50KG15QXJyYXkuc2hhcGUpXG5cbiMgSW5zcGVjdCB0aGUgc2l6ZSBvZiBgbXlBcnJheWBcbnByaW50KG15QXJyYXkuc2l6ZSkiLCJzY3QiOiJ0ZXN0X2Z1bmN0aW9uKFxuICAgIFwicHJpbnRcIixcbiAgICAxLFxuICAgIG5vdF9jYWxsZWRfbXNnPVwiRGlkIHlvdSBwcmludCBvdXQgYG15QXJyYXkuZGF0YWA/XCIsXG4gICAgaW5jb3JyZWN0X21zZz1cIkRvbid0IGZvcmdldCB0byBwcmludCBvdXQgdGhlIGRhdGEgb2YgYG15QXJyYXlgIVwiLFxuICAgIGRvX2V2YWw9RmFsc2VcbilcbnRlc3RfZnVuY3Rpb24oXG4gICAgXCJwcmludFwiLFxuICAgIDIsXG4gICAgbm90X2NhbGxlZF9tc2c9XCJEaWQgeW91IHByaW50IG91dCBgbXlBcnJheS5kdHlwZWA/XCIsXG4gICAgaW5jb3JyZWN0X21zZz1cIkRvbid0IGZvcmdldCB0byBwcmludCBvdXQgdGhlIGRhdGEgdHlwZSBvZiBgbXlBcnJheWAhXCIsXG4gICAgZG9fZXZhbD1GYWxzZVxuKVxudGVzdF9mdW5jdGlvbihcbiAgICBcInByaW50XCIsXG4gICAgMyxcbiAgICBub3RfY2FsbGVkX21zZz1cIkRpZCB5b3UgcHJpbnQgb3V0IGBteUFycmF5LnNoYXBlYD9cIixcbiAgICBpbmNvcnJlY3RfbXNnPVwiRG9uJ3QgZm9yZ2V0IHRvIHByaW50IG91dCB0aGUgc2hhcGUgb2YgYG15QXJyYXlgIVwiLFxuICAgIGRvX2V2YWw9RmFsc2VcbilcbnRlc3RfZnVuY3Rpb24oXG4gICAgXCJwcmludFwiLFxuICAgIDQsXG4gICAgbm90X2NhbGxlZF9tc2c9XCJEaWQgeW91IHByaW50IG91dCB0aGUgYG15QXJyYXkuc2l6ZWA/XCIsXG4gICAgaW5jb3JyZWN0X21zZz1cIkRvbid0IGZvcmdldCB0byBwcmludCBvdXQgdGhlIHNpemUgb2YgYG15QXJyYXlgIVwiLFxuICAgIGRvX2V2YWw9RmFsc2VcbilcbnN1Y2Nlc3NfbXNnKFwiV2VsbCBkb25lIVwiKSJ9

Verás en los resultados del bloque anterior que el tipo de dato de myArray es int64. Cuando trabajes intensivamente con arrays, recordarás que existen formas de convertirlos de un tipo de dato a otro con el método astype().

Aun así, cuando uses SciPy y NumPy juntos, también te pueden resultar muy útiles las siguientes funciones de manejo de tipos de NumPy, especialmente cuando trabajes con números complejos:

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wXG5teUFycmF5ID0gbnAuYXJyYXkoW1sxKzVqLDIsMys2al0sWzQrMWosNSw2KzJqXV0pIiwic2FtcGxlIjoiIyBSZXR1cm4gdGhlIHJlYWwgcGFydCBvZiBgbXlBcnJheWAgZWxlbWVudHNcbm5wLnJlYWwobXlBcnJheSlcblxuIyBSZXR1cm4gdGhlIGltYWdpbmFyeSBwYXJ0IG9mIGBteUFycmF5YCBlbGVtZW50c1xubnAuaW1hZyhteUFycmF5KVxuXG4jIFJldHVybiBhIHJlYWwgYXJyYXkgaWYgdGhlIGNvbXBsZXggcGFydHMgYXJlIGNsb3NlIHRvIDBcbm5wLnJlYWxfaWZfY2xvc2UobXlBcnJheSx0b2w9MTAwMClcblxuIyBDYXN0IGBteUFycmF5YCB0byBmbG9hdFxubnAuY2FzdFsnZiddKG15QXJyYXkpIn0=

Intenta añadir llamadas a print() para ver los resultados del código anterior. Verás que los números complejos tienen parte real e imaginaria. Las funciones np.real() y np.imag() están pensadas para devolver, respectivamente, esas partes.

Como alternativa, también puedes usar np.cast para convertir un objeto array a otro tipo de dato, como float en el ejemplo anterior.

Lo único que puede resultar más complicado en el bloque anterior es la función np.real_if_close(). Si le pasas una entrada compleja, como myArray, te devolverá un array real si las partes complejas están cerca de cero. Este «cerca de 0» puedes ajustarlo con el argumento tol que se pasa a la función. Juega con el umbral para ver qué ocurre.

Creación de arrays

Ya has visto cómo inspeccionar tu array y ajustar su tipo de dato, pero aún no has visto explícitamente cómo crear arrays. Ya sabes que puedes usar np.array() para hacerlo, pero hay otras rutinas de creación de arrays que deberías conocer: np.eye() y np.identity().

La función np.eye() te permite crear una matriz cuadrada con dimensiones iguales al entero positivo que pases como argumento. Sus elementos se rellenan con ceros, salvo la diagonal principal, que se rellena con unos. La función np.identity() funciona igual y también devuelve una matriz identidad.

Sin embargo, ten en cuenta que np.eye() puede recibir un argumento adicional, k, para indicar el índice de la diagonal que quieres poblar con unos.

Otras funciones de creación de arrays que te serán muy útiles cuando trabajes con matrices para álgebra lineal son las siguientes:

  • np.arange() crea un array con valores espaciados uniformemente entre dos números. Puedes especificar el salto entre elementos,
  • np.linspace() también genera valores uniformemente espaciados, pero aquí especificas el número de elementos que quieres en el array.
  • Por último, np.logspace() también crea arrays con valores espaciados uniformemente, pero en una escala logarítmica. Es decir, el espaciado es logarítmico: dos números están equiespaciados entre los logaritmos (base 10) de esos dos valores.

Estas funciones crean arrays en forma de mallas, que pueden usarse para crear rejillas (mesh grids), de las que ya leíste antes en esta publicación.

Ten en cuenta que en el siguiente bloque numpy ya está importado como np.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wIiwic2FtcGxlIjoiIyBDcmVhdGUgYSAyWDIgaWRlbnRpdHkgbWF0cml4IHdpdGggYG5wLmV5ZSgpYFxuX19fX19fX19fX19fX19fX19fXG5cbiMgQ3JlYXRlIGEgM1gzIGlkZW50aXR5IG1hdHJpeCB3aXRoIGBucC5pZGVudGl0eSgpYFxuX19fX19fX19fX19fX19fX19fXG5cbiMgVW5pZm9ybWx5IHNwYWNlZCB2YWx1ZXM6IHNwYWNpbmdcbl9fX19fX19fXygzLCA3LCAyKVxuXG4jIFVuaWZvcm1seSBzcGFjZWQgdmFsdWVzOiBudW1iZXIgb2Ygc2FtcGxlc1xuX19fX19fX19fX18oMiwgMywgNSlcblxuIyBVbmlmb3JtbHkgc3BhY2VkIHZhbHVlczogbG9nYXJpdGhtaWMgc3BhY2luZyBcbl9fX19fX19fX19fKDIsIDMsIDQpIiwic29sdXRpb24iOiIjIENyZWF0ZSBhIDJYMiBpZGVudGl0eSBtYXRyaXggd2l0aCBgbnAuZXllKClgXG5ucC5leWUoMilcblxuIyBDcmVhdGUgYSAzWDMgaWRlbnRpdHkgbWF0cml4IHdpdGggYG5wLmlkZW50aXR5KClgXG5ucC5pZGVudGl0eSgzKVxuXG4jIFVuaWZvcm1seSBzcGFjZWQgdmFsdWVzOiBzcGFjaW5nXG5ucC5hcmFuZ2UoMywgNywgMilcblxuIyBVbmlmb3JtbHkgc3BhY2VkIHZhbHVlczogbnVtYmVyIG9mIHNhbXBsZXNcbm5wLmxpbnNwYWNlKDIsIDMsIDUpXG5cbiMgVW5pZm9ybWx5IHNwYWNlZCB2YWx1ZXM6IGxvZ2FyaXRobWljIHNwYWNpbmcgXG5ucC5sb2dzcGFjZSgyLCAzLCA0KSIsInNjdCI6InRlc3RfZnVuY3Rpb24oXCJudW1weS5leWVcIiwgYXJncz1bMF0sIGluY29ycmVjdF9tc2c9XCJEaWQgeW91IHVzZSBgbnAuZXllKClgIHRvIGNyZWF0ZSBhIDJ4MiBpZGVudGl0eSBtYXRyaXg/XCIpXG50ZXN0X2Z1bmN0aW9uKFwibnVtcHkuaWRlbnRpdHlcIiwgYXJncz1bMF0sIGluY29ycmVjdF9tc2c9XCJEaWQgeW91IHVzZSBgbnAuaWRlbnRpdHkoKWAgdG8gY3JlYXRlIGEgM3gzIGlkZW50aXR5IG1hdHJpeD9cIilcbnRlc3RfZnVuY3Rpb24oXCJudW1weS5hcmFuZ2VcIilcbnRlc3RfZnVuY3Rpb24oXCJudW1weS5saW5zcGFjZVwiKVxudGVzdF9mdW5jdGlvbihcIm51bXB5LmxvZ3NwYWNlXCIpXG5zdWNjZXNzX21zZyhcIkdyZWF0IGpvYiFcIikifQ==

Ahora que has refrescado la memoria y sabes cómo manejar los tipos de datos de tus arrays, toca abordar el indexado y el slicing.

Indexado y slicing

Con el indexado, básicamente usas corchetes [] para acceder a los valores de un array. En otras palabras, puedes indexar si quieres acceder a elementos concretos, un subconjunto del array. El slicing es muy similar al subsetting, pero puedes considerarlo algo más avanzado: al hacer slicing de un array no apuntas solo a valores concretos, sino que trabajas con «regiones» de datos en lugar de «posiciones» exactas.

Refresca ambos conceptos con los siguientes ejemplos:

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wXG5teUFycmF5ID0gbnAuYXJyYXkoWzEsMiwzLDRdKVxubXlfMmRBcnJheSA9IG5wLmFycmF5KFtbMSwyLDMsNF0sIFs1LDYsNyw4XV0sIGR0eXBlPW5wLmludDY0KVxubXlfM2RBcnJheSA9IG5wLmFycmF5KFtbWzEsMiwzLDRdLCBbNSw2LDcsOF1dLCBbWzEsMiwzLDRdLCBbOSwxMCwxMSwxMl1dXSwgZHR5cGU9bnAuaW50NjQpIiwic2FtcGxlIjoiIyBTbGljZSBgbXlBcnJheWAgYXQgaW5kZXggMCBhbmQgMVxucHJpbnQoX19fX19fX19fX19fKVxuXG4jIFNsaWNlIGBteV8yZEFycmF5YCBhdCByb3cgMCBhbmQgMSwgY29sdW1uIDFcbnByaW50KF9fX19fX19fX19fX19fX18pXG5cbiMgU2xpY2UgYG15XzNkQXJyYXlgIGF0IHJvdyAxXG5wcmludChteV8zZEFycmF5WzEsLi4uXSlcblxuIyBCb29sZWFuIGluZGV4aW5nOiBvbmx5IHZhbHVlcyA8IDJcbnByaW50KG15QXJyYXlbX19fX19fX19fX19fXSlcblxuIyBGYW5jeSBpbmRleGluZ1xucHJpbnQobXlfMmRBcnJheVtbMSwgMCwgMSwgMF0sWzAsIDEsIDIsIDBdXSkiLCJzb2x1dGlvbiI6IiMgU2xpY2UgYG15QXJyYXlgIGF0IGluZGV4IDAgYW5kIDFcbnByaW50KG15QXJyYXlbMDoyXSlcblxuIyBTbGljZSBgbXlfMmRBcnJheWAgYXQgcm93IDAgYW5kIDEsIGNvbHVtbiAxXG5wcmludChteV8yZEFycmF5WzA6MiwxXSlcblxuIyBTbGljZSBgbXlfM2RBcnJheWAgYXQgcm93IDFcbnByaW50KG15XzNkQXJyYXlbMSwuLi5dKVxuXG4jIEJvb2xlYW4gaW5kZXhpbmc6IG9ubHkgdmFsdWVzIDwgMlxucHJpbnQobXlBcnJheVtteUFycmF5PDJdKVxuXG4jIEZhbmN5IGluZGV4aW5nXG5wcmludChteV8yZEFycmF5W1sxLCAwLCAxLCAwXSxbMCwgMSwgMiwgMF1dKSIsInNjdCI6InRlc3RfZnVuY3Rpb24oXG4gICAgXCJwcmludFwiLFxuICAgIDEsXG4gICAgbm90X2NhbGxlZF9tc2c9XCJEaWQgeW91IHByaW50IG91dCBgbXlBcnJheVswOjJdYD9cIixcbiAgICBpbmNvcnJlY3RfbXNnPVwiRG9uJ3QgZm9yZ2V0IHRvIHNsaWNlIGBteUFycmF5YCBhdCBpbmRleCAwIGFuZCAxIVwiLFxuICAgIGRvX2V2YWw9RmFsc2VcbilcbnRlc3RfZnVuY3Rpb24oXG4gICAgXCJwcmludFwiLFxuICAgIDIsXG4gICAgbm90X2NhbGxlZF9tc2c9XCJEaWQgeW91IHByaW50IG91dCBgbXlfMmRBcnJheVswOjIsMV1gP1wiLFxuICAgIGluY29ycmVjdF9tc2c9XCJEb24ndCBmb3JnZXQgdG8gc2xpY2UgYG15XzJkQXJyYXlgIGF0IGluZGV4IDAgYW5kIDEsIGNvbHVtbiAxIVwiLFxuICAgIGRvX2V2YWw9RmFsc2VcbilcbnRlc3RfZnVuY3Rpb24oXG4gICAgXCJwcmludFwiLFxuICAgIDMsXG4gICAgbm90X2NhbGxlZF9tc2c9XCJEaWQgeW91IHByaW50IG91dCBgbXlfM2RBcnJheVsxLC4uLl1gP1wiLFxuICAgIGluY29ycmVjdF9tc2c9XCJEb24ndCBmb3JnZXQgdG8gc2xpY2UgYG15XzNkQXJyYXlgIGF0IHJvdyAxIVwiLFxuICAgIGRvX2V2YWw9RmFsc2VcbilcbnRlc3RfZnVuY3Rpb24oXG4gICAgXCJwcmludFwiLFxuICAgIDQsXG4gICAgbm90X2NhbGxlZF9tc2c9XCJEaWQgeW91IHByaW50IG91dCBgbXlBcnJheVtteUFycmF5PDJdYD9cIixcbiAgICBpbmNvcnJlY3RfbXNnPVwiRG9uJ3QgZm9yZ2V0IHRvIGFkZCB0aGUgY29uZGl0aW9uIGBteUFycmF5PDJgIHRvIGBteUFycmF5YCFcIixcbiAgICBkb19ldmFsPUZhbHNlXG4pXG50ZXN0X2Z1bmN0aW9uKFxuICAgIFwicHJpbnRcIixcbiAgICA1LFxuICAgIG5vdF9jYWxsZWRfbXNnPVwiRGlkIHlvdSBwcmludCBvdXQgYG15XzJkQXJyYXlbWzEsIDAsIDEsIDBdLFswLCAxLCAyLCAwXV1gP1wiLFxuICAgIGRvX2V2YWw9RmFsc2VcbilcbnN1Y2Nlc3NfbXNnKFwiWWF5ISBZb3UncmUgYW4gZXhwZXJ0IGluIGluZGV4aW5nIGFuZCBzbGljaW5nIHdpdGggTnVtUHkhXCIpIn0=

Ahora que tienes fresco el slicing y el indexado, quizá te interesen algunos trucos de índices que pueden hacer tu trabajo más eficiente cuando te metas en cómputo científico con SciPy. Hay cuatro funciones que verás a menudo: np.mgrid(), np.ogrid(), np.r y np.c.

Puede que ya conozcas las dos últimas si tienes algo de experiencia con NumPy. np.r y np.c se usan a menudo cuando necesitas apilar arrays por filas o por columnas, respectivamente. Con estas funciones puedes construir arrays rápidamente en lugar de usar np.concatenate().

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wXG5hcnJheSA9IG5wLmV5ZSgyKVxubXlfMmRBcnJheSA9IG5wLmFycmF5KFtbMSwyLDMsNF0sIFs1LDYsNyw4XV0sIGR0eXBlPW5wLmludDY0KSIsInNhbXBsZSI6IiMgQ3JlYXRlIGEgZGVuc2UgbWVzaGdyaWRcbm5wLm1ncmlkWzE6MTE6MiwgLTEyOi0zOjNdXG5cbiMgQ3JlYXRlIGFuIG9wZW4gbWVzaGdyaWRcbm5wLm9ncmlkWzE6MTE6MiwgLTEyOi0zOjNdXG5cbiMgU3RhY2sgYXJyYXlzIHZlcnRpY2FsbHlcbm5wLnJfWzMsWzBdKjUsLTE6MToxMGpdXG5cbiMgU3RhY2sgYXJyYXlzIGhvcml6b250YWxseSBcbm5wLmNfW2FycmF5LCBteV8yZEFycmF5XSJ9

Al ver las dos primeras de estas funciones quizá te preguntes para qué necesitas una meshgrid. Puedes usarlas para generar dos arrays que contengan las coordenadas x e y en cada posición de una rejilla rectangular. La función np.meshgrid() toma dos arrays 1D y produce dos matrices 2D correspondientes a todos los pares (x, y) de ambos arrays.

  • np.mgrid() es una implementación del meshgrid de MATLAB y devuelve arrays con la misma forma. Esto significa que las dimensiones y el número de arrays de salida son iguales al número de dimensiones de indexado.
  • np.ogrid(), en cambio, genera una meshgrid abierta y no es tan densa como el resultado de np.mgrid(). Puedes ver la diferencia visual en el bloque anterior.

Puedes leer más sobre las diferencias entre ambas aquí.

Otra función que puedes usar para indexado/slicing es np.select(). Te permite devolver valores de una lista de arrays en función de condiciones que defines en el primer argumento. En el segundo argumento pasas el array que quieres considerar para esta selección.

Prueba este ejemplo:

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wIiwic2FtcGxlIjoiIyBJbml0aWFsaXplIGEgMkQgYXJyYXkgXG5teV8yZEFycmF5ID0gbnAuYXJyYXkoW1sxLDIsMyw0XSwgWzUsNiw3LDhdXSwgZHR5cGU9bnAuaW50NjQpXG5cbiMgU2VsZWN0IHZhbHVlcyBmcm9tIGBteV8yZEFycmF5YFxubnAuc2VsZWN0KFtteV8yZEFycmF5IDwgNF0sW215XzJkQXJyYXkgKiAyXSkifQ==

¡Genial! Ahora que has seleccionado los valores correctos del array original, aún puedes elegir la forma y manipular tu nuevo array.

Selección y manipulación de la forma

NumPy ofrece muchas formas de seleccionar y manipular la forma de tus arrays, y seguramente ya conozcas bastantes. La siguiente sección solo da un breve repaso de funciones útiles, así que no cubre todas.

¿Hay funciones especialmente útiles cuando trabajas con SciPy?

Sí: las que ayudan a aplanar arrays, apilarlos y dividirlos. Ya has visto las funciones np.c y np.r, que a menudo preferirás a np.concatenate(), pero hay muchas más que deberías conocer.

Por ejemplo, np.hstack() para apilar arrays horizontalmente o np.vstack() para apilarlos verticalmente. De forma similar, puedes usar np.vsplit() y np.hsplit() para dividir tus arrays vertical y horizontalmente. Pero probablemente esto ya te suene.

Demuéstralo en el siguiente bloque:

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wXG5teUFycmF5ID0gbnAuYXJyYXkoWzEsMiwzLDRdKVxubXlfMmRBcnJheSA9IG5wLmFycmF5KFtbMSwyLDMzNF0sIFs1LDYsNyw4XV0sIGR0eXBlPW5wLmludDY0KVxubXlfM2RBcnJheSA9IG5wLmFycmF5KFtbWzEsMiwzLDRdLCBbNSw2LDcsOF1dLCBbWzEsMiwzLDRdLCBbOSwxMCwxMSwxMl1dXSwgZHR5cGU9bnAuaW50NjQpIiwic2FtcGxlIjoiI1N0YWNrIGFycmF5cyBob3Jpem9udGFsbHkgKGNvbHVtbi13aXNlKVxucHJpbnQoX19fX19fX19fKChucC5leWUoMiksIG15XzJkQXJyYXkpKSlcblxuIyBTdGFjayBhcnJheXMgdmVydGljYWxseSAocm93LXdpc2UpXG5wcmludChfX19fX19fX19fKChteUFycmF5LCBteV8yZEFycmF5KSkpXG5cbiMgU3BsaXQgdGhlIGFycmF5IGhvcml6b250YWxseSBhdCB0aGUgMm5kIGluZGV4XG5wcmludChfX19fX19fX19fXyhteV8yZEFycmF5LCAyKSlcblxuIyBTcGxpdCB0aGUgYXJyYXkgdmVydGljYWxseSBhdCB0aGUgMm5kIGluZGV4XG5wcmludChfX19fX19fX19fX18obXlfMmRBcnJheSwgMikpIiwic29sdXRpb24iOiIjU3RhY2sgYXJyYXlzIGhvcml6b250YWxseSAoY29sdW1uLXdpc2UpXG5wcmludChucC5oc3RhY2soKG5wLmV5ZSgyKSwgbXlfMmRBcnJheSkpKVxuXG4jIFN0YWNrIGFycmF5cyB2ZXJ0aWNhbGx5IChyb3ctd2lzZSlcbnByaW50KG5wLnZzdGFjaygobXlBcnJheSwgbXlfMmRBcnJheSkpKVxuXG4jIFNwbGl0IHRoZSBhcnJheSBob3Jpem9udGFsbHkgYXQgdGhlIDJuZCBpbmRleFxucHJpbnQobnAuaHNwbGl0KG15XzJkQXJyYXksIDIpKVxuXG4jIFNwbGl0IHRoZSBhcnJheSB2ZXJ0aWNhbGx5IGF0IHRoZSAybmQgaW5kZXhcbnByaW50KG5wLnZzcGxpdChteV8yZEFycmF5LCAyKSkiLCJzY3QiOiJ0ZXN0X2Z1bmN0aW9uKFxuICAgIFwicHJpbnRcIixcbiAgICAxLFxuICAgIG5vdF9jYWxsZWRfbXNnPVwiRGlkIHlvdSBwcmludCBvdXQgYG5wLmhzdGFjaygobnAuZXllKDIpLCBteV8yZEFycmF5KSlgP1wiLFxuICAgIGluY29ycmVjdF9tc2c9XCJEb24ndCBmb3JnZXQgdG8gc3RhY2sgYG5wLmV5ZSgyKWAgYW5kIGBteV8yZEFycmF5YCBob3Jpem9udGFsbHkhXCIsXG4gICAgZG9fZXZhbD1GYWxzZVxuKVxudGVzdF9mdW5jdGlvbihcbiAgICBcInByaW50XCIsXG4gICAgMixcbiAgICBub3RfY2FsbGVkX21zZz1cIkRpZCB5b3UgcHJpbnQgb3V0IGBucC52c3RhY2sobXlBcnJheSwgbXlfMmRBcnJheSkpYD9cIixcbiAgICBpbmNvcnJlY3RfbXNnPVwiRG9uJ3QgZm9yZ2V0IHRvIHN0YWNrIGBteUFycmF5YCBhbmQgYG15XzJkQXJyYXlgIHZlcnRpY2FsbHkhXCIsXG4gICAgZG9fZXZhbD1GYWxzZVxuKVxudGVzdF9mdW5jdGlvbihcbiAgICBcInByaW50XCIsXG4gICAgMyxcbiAgICBub3RfY2FsbGVkX21zZz1cIkRpZCB5b3UgcHJpbnQgb3V0IGBucC5oc3BsaXQobXlfMmRBcnJheSwgMilgP1wiLFxuICAgIGluY29ycmVjdF9tc2c9XCJEb24ndCBmb3JnZXQgdG8gaG9yaXpvbnRhbGx5IHNwbGl0IGBteV8yZEFycmF5YCBhdCB0aGUgMm5kIGluZGV4IVwiLFxuICAgIGRvX2V2YWw9RmFsc2VcbilcbnRlc3RfZnVuY3Rpb24oXG4gICAgXCJwcmludFwiLFxuICAgIDQsXG4gICAgbm90X2NhbGxlZF9tc2c9XCJEaWQgeW91IHByaW50IG91dCBgbnAudnNwbGl0KG15XzJkQXJyYXksIDIpYD9cIixcbiAgICBpbmNvcnJlY3RfbXNnPVwiRG9uJ3QgZm9yZ2V0IHRvIHZlcnRpY2FsbHkgc3BsaXQgYG15XzJkQXJyYXlgIGF0IGluZGV4IDIhXCIsXG4gICAgZG9fZXZhbD1GYWxzZVxuKVxuc3VjY2Vzc19tc2coXCJZb3UncmUgYSB0cnVlIG1hc3RlciBpbiBzdGFja2luZyBhbmQgc3BsaXR0aW5nIGFycmF5cyFcIikifQ==

Recuerda que np.eye() crea un array identidad 2x2, perfecto para apilar con el array 2D que se ha cargado en el bloque anterior.

Si quieres saber más sobre las condiciones a tener en cuenta para apilar arrays, ve aquí. En cualquier caso, también puedes mirar los arrays y lo que hacen las funciones para interiorizar las «reglas» que debes respetar si quieres unir dos arrays por filas o por columnas.

Al dividir arrays, lo más importante probablemente sea la forma del array, porque querrás seleccionar el índice correcto en el que realizar el corte.

Además de las rutinas para apilar y dividir arrays y de las funciones que te permiten manipularlos, hay algo llamado «vectorización» que debes considerar. Cuando aplicas una función a un array, normalmente se aplica a cada elemento. Por ejemplo, si aplicas np.cos(), np.sin() o np.tan() a un array, verás que funcionan sobre todos los elementos. Cuando pase esto, sabrás que esa función está vectorizada.

Pero cuando definas funciones tú mismo, como probablemente harás al adentrarte en el cómputo científico, quizá también quieras vectorizarlas. En esos casos, puedes llamar a np.vectorize():

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wXG5teUFycmF5ID0gbnAuYXJyYXkoWzEsMiwzLDRdKSIsInNhbXBsZSI6IiMgRGVmaW5lIGEgZnVuY3Rpb24gYG15ZnVuY2BcbmRlZiBteWZ1bmMoYSxiKTpcbiAgaWYgYSA+IGI6XG4gICAgIHJldHVybiBhIC0gYlxuICBlbHNlOlxuICAgICByZXR1cm4gYSArIGJcbiAgICBcbiMgVmVjdG9yaXplIGBteWZ1bmNgXG52ZWN0b3JpemVkRnVuYyA9IG5wLnZlY3Rvcml6ZShteWZ1bmMpIFxuXG4jIEFwcGx5IFxudmVjdG9yaXplZEZ1bmMobXlBcnJheSwgMikifQ==

En cuanto a otras funciones matemáticas vectorizadas que deberías conocer, considera np.angle() para obtener el ángulo de los elementos complejos, además de las trigonométricas básicas, exponenciales o logarítmicas, que te serán muy útiles.

Learn Python for Data Science With DataCamp

Álgebra lineal con SciPy

Ahora que ya sabes lo necesario para aprovechar ambos paquetes, es momento de entrar en el tema del tutorial: el álgebra lineal.

Pero antes de ver cómo usar Python, asegúrate de que tu entorno de trabajo está listo.

Instalar SciPy

Por supuesto, lo primero es asegurarte de que tienes Python instalado. Ve a esta página si aún te falta :) Si trabajas en Windows, asegúrate de haber añadido Python a la variable de entorno PATH. Además, no olvides instalar un gestor de paquetes como pip, que te permitirá usar librerías open source de Python.

Ten en cuenta que las versiones recientes de Python 3 ya incluyen pip, así que comprueba si lo tienes y, si es así, actualízalo antes de instalar otros paquetes:

 pip install pip --upgrade pip --version

Pero no basta con instalar un gestor de paquetes; también necesitas descargar la wheel de la librería: ve aquí para conseguir tu wheel de SciPy. Tras la descarga, abre la terminal en el directorio de descarga en tu PC e instálala. Además, puedes comprobar si la instalación fue correcta y confirmar la versión del paquete que estás usando:

# Install the wheel install "scipy‑0.18.1‑cp36‑cp36m‑win_amd64.whl"# Confirm successful installimport scipy# Check package versionscipy.__version__

Después de estos pasos, ¡ya estás listo para empezar!

Consejo: instala el paquete descargando la distribución Anaconda de Python. Es una forma sencilla de empezar rápido, ya que Anaconda no solo incluye 100 de los paquetes más populares de Python, R y Scala para data science, sino que también trae varios entornos de desarrollo abiertos como Jupyter y Spyder. Si quieres empezar a trabajar con Jupyter Notebook, echa un vistazo a este tutorial de Jupyter Notebook.

Si aún no la has descargado, ve aquí para obtenerla.

Vectores y matrices: lo básico

Ahora que tu entorno está listo, por fin puedes empezar con álgebra lineal en Python. En esencia, esta disciplina estudia los espacios vectoriales y las aplicaciones lineales entre ellos. Estas aplicaciones pueden describirse con matrices, lo que además facilita el cálculo.

Recuerda que un espacio vectorial es un concepto fundamental en álgebra lineal. Es un espacio en el que tienes una colección de objetos (vectores) y donde puedes sumar o escalar dos vectores sin que el vector resultante salga del espacio. Recuerda también que los vectores son filas (o columnas) de una matriz.

¿Y cómo funciona esto en Python?

Puedes crear fácilmente un vector con np.array(). De forma similar, puedes dar estructura de matriz a cualquier ndarray de una o dos dimensiones con np.matrix() o np.mat().

Pruébalo en el siguiente bloque:

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wIiwic2FtcGxlIjoiIyBDcmVhdGUgYSB2ZWN0b3Jcbm15VmVjdG9yID0gbnAuYXJyYXkoWzEsMiwzLDRdKVxuXG4jIENyZWF0ZSBhIG1hdHJpeFxubXlNYXRyaXggPSBucC5tYXRyaXgobnAucmFuZG9tLnJhbmRvbSgoNSw1KSkpIn0=

Entonces, ¿arrays y matrices son lo mismo salvo por el formato?

No exactamente. Hay diferencias:

  • Una matriz es 2D, mientras que los arrays suelen ser de dimensión n,
  • Como ya insinuaban las funciones anteriores, la matriz es una subclase de ndarray,
  • Tanto arrays como matrices tienen .T(), pero solo las matrices tienen .H() y .I(),
  • La multiplicación de matrices es distinta de la multiplicación elemento a elemento de arrays, y
  • Además, la operación ** produce resultados diferentes para matrices y arrays

Cuando trabajes con matrices, a veces tendrás algunas en las que la mayoría de elementos son ceros. Estas se llaman «matrices dispersas» (sparse), mientras que las que tienen principalmente elementos no nulos se llaman «densas» (dense).

Puede parecer trivial, pero al usar SciPy para álgebra lineal esto puede marcar diferencia en los módulos que utilices. En concreto, puedes usar scipy.linalg para matrices densas, pero si trabajas con matrices dispersas, conviene revisar el módulo scipy.sparse, que también tiene su propio scipy.sparse.linalg.

Para matrices dispersas, hay bastantes opciones para crearlas. En el siguiente bloque se listan algunas:

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wXG5mcm9tIHNjaXB5IGltcG9ydCBzcGFyc2UgXG5DID0gbnAucmFuZG9tLnJhbmRvbSgoMTAsNSkpXG5DW0MgPiAwLjVdID0gMCAiLCJzYW1wbGUiOiIjIENyZWF0ZSBhIDJYMiBpZGVudGl0eSBtYXRyaXhcbm5wLmV5ZSgzLCBrPTEpICAgICAgICBcblxuIyBDcmVhdGUgYSAyeDIgaWRlbnRpdHkgbWF0cml4XG5ucC5tYXQobnAuaWRlbnRpdHkoMikpICAgICAgICAgXG5cbiMgQ29tcHJlc3NlZCBTcGFyc2UgUm93IG1hdHJpeFxuc3BhcnNlLmNzcl9tYXRyaXgoQykgIFxuXG4jIENvbXByZXNzZWQgU3BhcnNlIENvbHVtbiBtYXRyaXhcbnNwYXJzZS5jc2NfbWF0cml4KEMpICBcblxuIyBEaWN0aW9uYXJ5IE9mIEtleXMgbWF0cml4XG5zcGFyc2UuZG9rX21hdHJpeChDKSAgIn0=

Además, hay otras funciones que puedes usar para crear matrices dispersas: matrices Block Sparse Row con bsr_matrix(), matrices dispersas en formato COOrdinate con coo_matrix(), matrices dispersas en almacenamiento DIAgonal con dia_matrix() y matrices dispersas basadas en listas enlazadas por filas con lil_matrix().

Opciones hay muchas, pero ¿cuál elegir si vas a crear una matriz dispersa tú mismo?

No es tan difícil.

Básicamente, primero piensa cómo la vas a inicializar. Después, valora qué quieres hacer con tu matriz dispersa.

En concreto, puedes seguir esta lista para decidir el tipo de matriz dispersa a usar:

  • Si piensas rellenarla número a número, elige coo_matrix() o dok_matrix().
  • Si quieres inicializarla con un array como diagonal, usa dia_matrix().
  • Para matrices construidas por secciones, usa lil_matrix().
  • Si la construyes a partir de bloques de matrices más pequeñas, considera bsr_matrix().
  • Si quieres acceso rápido a filas y columnas, convierte tus matrices usando csr_matrix() y csc_matrix(), respectivamente. Estas dos últimas no son ideales para inicializar, pero al multiplicar notarás la diferencia de velocidad.

¡Así de fácil!

Operaciones con vectores

Ahora que has repasado la diferencia entre vectores, matrices densas y dispersas, toca mirar más de cerca los vectores y las operaciones matemáticas que puedes hacer con ellos. Aquí nos centramos en operaciones matemáticas para que veas similitudes y diferencias con las matrices, y porque gran parte del álgebra lineal, al final, es trabajar con matrices.

Ya has visto que puedes crear un vector con np.array(). Pero ahora que los tienes, querrás conocer algunas operaciones básicas que se pueden realizar. vector1 y vector2 ya están cargados en el siguiente bloque:

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wXG52ZWN0b3IxPW5wLmFycmF5KFsxLDIsM10pXG52ZWN0b3IyID0gbnAuYXJyYXkoWzIsMyw0XSkiLCJzYW1wbGUiOiIjIEFkZGl0aW9uIG9mIGB2ZWN0b3IxYCBhbmQgYHZlY3RvcjJgXG52ZWN0b3IzID0gdmVjdG9yMSArIHZlY3RvcjJcblxuIyBQcmludCBgdmVjdG9yM2BcbnByaW50KF9fX19fX18pXG5cbiMgU3VidHJhY3Rpb24gb2YgYHZlY3RvcjJgIGFuZCBgdmVjdG9yMWBcbnZlY3RvcjQgPSBfX19fX19fXyAtIHZlY3RvcjFcblxuIyBwcmludCBgdmVjdG9yNGBcbnByaW50KHZlY3RvcjQpXG5cbiMgRG90IHByb2R1Y3Qgb2YgYHZlY3RvcjFgIGFuZCBgdmVjdG9yMmBcbmRvdFByb2R1Y3QgPSBucC5kb3QodmVjdG9yMSwgdmVjdG9yMilcblxuIyBQcmludCBgZG90UHJvZHVjdGBcbnByaW50KGRvdFByb2R1Y3QpXG5cbiMgQ3Jvc3MgcHJvZHVjdCBvZiBgdmVjdG9yMWAgYW5kIGB2ZWN0b3IyYFxuY3Jvc3NQcm9kdWN0ID0gbnAuY3Jvc3MoX19fX19fX18sIHZlY3RvcjIpXG5cbiMgUHJpbnQgYGNyb3NzUHJvZHVjdGBcbnByaW50KF9fX19fX19fX19fXykiLCJzb2x1dGlvbiI6IiMgQWRkaXRpb24gb2YgYHZlY3RvcjFgIGFuZCBgdmVjdG9yMmBcbnZlY3RvcjMgPSB2ZWN0b3IxICsgdmVjdG9yMlxuXG4jIFByaW50IGB2ZWN0b3IzYCBvZiBgdmVjdG9yMmAgYW5kIGB2ZWN0b3IxYFxucHJpbnQodmVjdG9yMylcblxuIyBTdWJ0cmFjdGlvblxudmVjdG9yNCA9IHZlY3RvcjIgLSB2ZWN0b3IxXG5cbiMgcHJpbnQgYHZlY3RvcjRgXG5wcmludCh2ZWN0b3I0KVxuXG4jIERvdCBwcm9kdWN0IG9mIGB2ZWN0b3IxYCBhbmQgYHZlY3RvcjJgXG5kb3RQcm9kdWN0ID0gbnAuZG90KHZlY3RvcjEsIHZlY3RvcjIpXG5cbiMgUHJpbnQgYGRvdFByb2R1Y3RgXG5wcmludChkb3RQcm9kdWN0KVxuXG4jIENyb3NzIHByb2R1Y3Qgb2YgYHZlY3RvcjFgIGFuZCBgdmVjdG9yMmBcbmNyb3NzUHJvZHVjdCA9IG5wLmNyb3NzKHZlY3RvcjEsIHZlY3RvcjIpXG5cbiMgUHJpbnQgYGNyb3NzUHJvZHVjdGBcbnByaW50KGNyb3NzUHJvZHVjdCkiLCJzY3QiOiJ0ZXN0X29iamVjdChcInZlY3RvcjNcIilcbnRlc3RfZnVuY3Rpb24oXCJwcmludFwiLCBpbmRleD0xKVxudGVzdF9vYmplY3QoXCJ2ZWN0b3I0XCIpXG50ZXN0X2Z1bmN0aW9uKFwicHJpbnRcIiwgaW5kZXg9MilcbnRlc3Rfb2JqZWN0KFwiZG90UHJvZHVjdFwiKVxudGVzdF9mdW5jdGlvbihcInByaW50XCIsIGluZGV4PTMpXG50ZXN0X29iamVjdChcImNyb3NzUHJvZHVjdFwiKVxudGVzdF9mdW5jdGlvbihcInByaW50XCIsIGluZGV4PTQpXG5zdWNjZXNzX21zZyhcIldlbGwgZG9uZSFcIikifQ==

Ahora que ya has visto algunas operaciones con vectores, es momento de ponerse con el trabajo real de matrices.

Matrices: operaciones y rutinas

Igual que al comienzo de la sección anterior, ya sabes crear matrices, pero aún no cómo sacarles partido. Esta sección te ofrece un repaso de funciones y rutinas básicas para trabajar con matrices de forma eficiente.

Primero, veamos algunas funciones. Si ya has trabajado con NumPy, te resultarán familiares, y aunque no, verás que son fáciles de usar.

Miremos algunos ejemplos.

Están np.add() y np.subtract() para sumar y restar arrays o matrices, y también np.divide() y np.multiply para división y multiplicación. No tiene mucho misterio, ¿verdad? La función np.dot() que viste en la sección anterior para calcular el producto escalar también puede usarse con matrices. No olvides pasar dos matrices en lugar de vectores.

¿Básico? Vamos un poco más allá. Para multiplicaciones, también tienes otras funciones como np.vdot() para el producto escalar de vectores, np.inner() u np.outer() para productos interior o exterior de arrays, np.tensordot() y np.kron() para el producto de Kronecker de dos arrays:

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wXG5tYXRyaXgxID0gbnAubWF0cml4KG5wLnJhbmRvbS5yYW5kb20oKDIsMikpKVxubWF0cml4MiA9IG5wLm1hdChbWzMsNF0sIFs1LDZdXSlcbnZlY3RvcjE9bnAuYXJyYXkoWzEsMiwzXSlcbnZlY3RvcjIgPSBucC5hcnJheShbMiwzLDRdKSIsInNhbXBsZSI6IiMgVmVjdG9yIGRvdCBwcm9kdWN0XG52ZWN0b3JEb3RQcm9kdWN0ID0gbnAudmRvdCh2ZWN0b3IxLCB2ZWN0b3IyKVxuXG4jIElubmVyIHByb2R1Y3RcbmlubmVyUHJvZHVjdCA9IG5wLmlubmVyKHZlY3RvcjEsIHZlY3RvcjIpXG5cbiMgT3V0ZXIgcHJvZHVjdFxub3V0ZXJQcm9kdWN0ID0gbnAub3V0ZXIodmVjdG9yMSwgdmVjdG9yMilcblxuIyBUZW5zb3IgZG90IHByb2R1Y3RcbnRlbnNvckRvdFByb2R1Y3QgPSBucC50ZW5zb3Jkb3QobWF0cml4MSwgbWF0cml4MilcblxuIyBLcm9uZWNrZXIgcHJvZHVjdFxua3JvblByb2R1Y3QgPSBucC5rcm9uKG1hdHJpeDEsIG1hdHJpeDIpIn0=

Consejo: añade sentencias print al bloque anterior para ver los resultados de cada producto.

Además, te puede resultar útil considerar algunas funciones del módulo linalg: las funciones exponenciales de matrices linalg.expm(), linalg.expm2() y linalg.expm3(). La diferencia entre ellas está en cómo calculan la exponencial. Quédate con la primera para una exponencial matricial general, pero prueba las tres para ver las diferencias.

También tienes funciones trigonométricas como linalg.cosm(), linalg.sinm() y linalg.tanm(); trigonométricas hiperbólicas como linalg.coshm(), linalg.sinhm() y linalg.tanhm(); la función signo linalg.signm(); el logaritmo matricial linalg.logm(); y la raíz cuadrada matricial linalg.sqrtm().

Además, puedes evaluar una función de matriz con linalg.funm(). Mira el ejemplo:

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiZnJvbSBzY2lweSBpbXBvcnQgbGluYWxnXG5pbXBvcnQgbnVtcHkgYXMgbnAgXG5teU1hdHJpeCA9IG5wLm1hdHJpeChucC5yYW5kb20ucmFuZG9tKCg1LDUpKSkiLCJzYW1wbGUiOiJsaW5hbGcuZnVubShteU1hdHJpeCwgbGFtYmRhIHg6IHgqeCkifQ==

Pasas como primer argumento la matriz a la que quieres aplicar la función y, como segundo, una función (en este caso, una lambda) que quieres aplicar a esa matriz. Ten en cuenta que la función que pases a linalg.funm() debe estar vectorizada.

Ahora veamos algunas rutinas básicas con matrices. Lo primero que querrás probar son los atributos de matriz: T para la transposición, H para la trasposición conjugada, I para la inversa y A para convertir a array.

Pruébalos:

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wIFxubXlNYXRyaXggPSBucC5tYXRyaXgobnAucmFuZG9tLnJhbmRvbSgoNSw1KSkpIiwic2FtcGxlIjoiIyBUcmFuc3Bvc2l0aW9uXG5teU1hdHJpeC5fXG5cbiMgQ29uanVnYXRlIHRyYW5zcG9zaXRpb25cbm15TWF0cml4Ll9cblxuIyBJbnZlcnNlXG5teU1hdHJpeC5fXG5cbiMgQXJyYXlcbm15TWF0cml4Ll8iLCJzb2x1dGlvbiI6IiMgVHJhbnNwb3NpdGlvblxubXlNYXRyaXguVFxuXG4jIENvbmp1Z2F0ZSB0cmFuc3Bvc2l0aW9uXG5teU1hdHJpeC5IXG5cbiMgSW52ZXJzZVxubXlNYXRyaXguSVxuXG4jIEFycmF5XG5teU1hdHJpeC5BIiwic2N0IjoidGVzdF9vYmplY3RfYWNjZXNzZWQoXCJteU1hdHJpeC5UXCIpXG50ZXN0X29iamVjdF9hY2Nlc3NlZChcIm15TWF0cml4LkhcIilcbnRlc3Rfb2JqZWN0X2FjY2Vzc2VkKFwibXlNYXRyaXguSVwiKVxudGVzdF9vYmplY3RfYWNjZXNzZWQoXCJteU1hdHJpeC5BXCIpXG5zdWNjZXNzX21zZyhcIkF3ZXNvbWUhXCIpIn0=

Cuando transpónese una matriz, creas una nueva en la que las filas son las columnas de la original. En la trasposición conjugada, en cambio, se intercambian los índices de filas y columnas de cada elemento de la matriz. La inversa de una matriz es otra que, al multiplicarla por la original, produce una matriz identidad.

Además de esos atributos, también hay funciones para realizar rutinas básicas, como np.transpose() y linalg.inv() para transponer y obtener la inversa, respectivamente.

También puedes obtener la traza, es decir, la suma de los elementos de la diagonal principal, con np.trace(). De forma similar, puedes obtener el rango de una matriz, o el número de valores singulares de una descomposición SVD mayores que un cierto umbral, con linalg.matrix_rank de NumPy.

No te preocupes si el rango de la matriz no te encaja aún; verás más sobre ello más adelante.

Por ahora, céntrate en dos rutinas más que puedes usar:

  • La norma de una matriz se puede calcular con linalg.norm: es un número definido en función de sus elementos. La norma es una magnitud útil que te da información importante sobre una matriz porque te indica cuán grandes son sus elementos.
  • Además, puedes calcular el determinante con linalg.det(), un valor que se obtiene a partir de los elementos de una matriz cuadrada. El determinante resume una matriz cuadrada en un número único que determina si esa matriz es invertible o no.

Por último, resolver grandes sistemas de ecuaciones lineales es una de las aplicaciones más básicas de las matrices. Si tienes un sistema \(Ax = b\), donde \(A\) es una matriz cuadrada y \(b\) una matriz general, tienes dos métodos que puedes usar para encontrar \(x\), dependiendo del tipo de matriz con el que trabajes:

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wXG5mcm9tIHNjaXB5IGltcG9ydCBsaW5hbGdcbkEgPSBucC5tYXRyaXgobnAucmFuZG9tLnJhbmRvbSgoMiwyKSkpXG5hID0gbnAuYXJyYXkoWzEsMiwzXSlcbkUgPSBucC5tYXQoYSkuVFxuYiA9IG5wLmFycmF5KFsoMSs1aiwyaiwzaiksICg0aiw1aiw2aildKVxuRiA9IG5wLmV5ZSgzLCBrPTEpIiwic2FtcGxlIjoiIyBEZW5zZSBtYXRyaXggc29sdmVyXG5saW5hbGcuc29sdmUoQSwgYilcblxuIyBMaW5lYXIgbGVhc3Qtc3F1YXJlIHNvbHZlclxubGluYWxnLmxzdHNxKEYsRSkifQ==

Para resolver matrices dispersas, puedes usar linalg.spsolve(). Cuando no puedas resolver la ecuación, puede que aún sea posible obtener una aproximación de \(x\) con el comando linalg.lstsq().

Consejo: no te pierdas la chuleta de SciPy de DataCamp.

Ahora que ya tienes una idea de cómo crear matrices y usarlas en operaciones matemáticas, es momento de abordar temas más avanzados que necesitarás para meterte de lleno en machine learning.

Autovalores y autovectores

El primer tema que trataremos son los autovalores y autovectores.

Los autovalores son una nueva forma de mirar al corazón de una matriz. Pero antes, aclaremos qué son los autovectores. Casi todos los vectores cambian de dirección cuando se multiplican por una matriz. Sin embargo, hay ciertos vectores «especiales» que quedan en la misma dirección tras la multiplicación. Esos son los autovectores.

En otras palabras, si multiplicas un autovector por una matriz, el vector resultante es igual al autovector original multiplicado por \(\lambda\), el autovalor: \[Ax = \lambda x. \]

Esto significa que el autovalor te da información valiosa: te dice si uno de los autovectores se estira, se contrae, se invierte o queda igual cuando se multiplica por una matriz.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wXG5pbXBvcnQgc2NpcHlcbmZyb20gc2NpcHkgaW1wb3J0IGxpbmFsZyBcbm15TWF0cml4ID0gbnAubWF0cml4KG5wLnJhbmRvbS5yYW5kb20oKDIsMikpKSIsInNhbXBsZSI6IiMgU29sdmUgZWlnZW52YWx1ZSBwcm9ibGVtXG5sYSwgdiA9IGxpbmFsZy5laWcobXlNYXRyaXgpIFxuXG4jIFVucGFjayBlaWdlbnZhbHVlc1xubDEsIGwyID0gbGFcblxuIyBGaXJzdCBlaWdlbnZlY3Rvclxudls6LDBdXG5cbiMgU2Vjb25kIGVpZ2VudmVjdG9yXG52WzosMV1cblxuIyBPciB1bnBhY2sgZWlnZW52YWx1ZXMgd2l0aCBgZWlndmFscygpYFxubGluYWxnLmVpZ3ZhbHMobXlNYXRyaXgpIn0=

Usas la función eig() del módulo linalg de SciPy para resolver problemas de autovalores y autovectores, ordinarios o generalizados, en matrices cuadradas.

Ten en cuenta que la función eigvals() es otra forma de obtener los autovalores de una matriz.

Cuando trabajes con matrices dispersas, puedes recurrir al módulo scipy.sparse para obtener las funciones adecuadas y hallar autovalores y autovectores:

la, v = sparse.linalg.eigs(myMatrix,1)

Ten en cuenta que el código anterior especifica el número de autovalores y autovectores a recuperar: 1.

Los autovalores y autovectores son conceptos importantes en muchas técnicas de visión por computador y machine learning, como el Análisis de Componentes Principales (PCA) para reducción de dimensionalidad y EigenFaces para reconocimiento facial.

Descomposición en valores singulares (SVD)

Siguiente parada: SVD, imprescindible si quieres aprender data science de verdad. La descomposición en valores singulares de una matriz \(A\) es la descomposición o factorización de \(A\) en el producto de tres matrices: \(A = U * \Sigma * V^t\).

Los tamaños de cada matriz, si sabes que \(A\) es de tamaño \(M\) x \(N\), son:

  • \(U\) es de tamaño \(M\) x \(M\)
  • \(V\) es de tamaño \(N\) x \(N\)
  • \(\Sigma\) es de tamaño \(M\) x \(N\)

El símbolo \(*\) indica multiplicación de matrices y el \(^t\) en \(V^t\) significa que la matriz está transpuesta: filas y columnas intercambiadas.

Dicho simple, la SVD proporciona una forma de descomponer una matriz en piezas más simples y con significado. Esas piezas pueden contener la información que nos interesa.

eyJsYW5ndWFnZSI6InB5dGhvbiIsInByZV9leGVyY2lzZV9jb2RlIjoiaW1wb3J0IG51bXB5IGFzIG5wXG5mcm9tIHNjaXB5IGltcG9ydCBsaW5hbGdcbmIgPSBucC5hcnJheShbKDErNWosMmosM2opLCAoNGosNWosNmopXSlcbm15TWF0cml4ID0gbnAuYXNtYXRyaXgoYikiLCJzYW1wbGUiOiIjIFNpbmd1bGFyIFZhbHVlIERlY29tcG9zaXRpb25cblUscyxWaCA9IGxpbmFsZy5zdmQobXlNYXRyaXgpIFxuXG4jIEluaXRpYWxpemUgYE1gIGFuZCBgTmBcbk0sTiA9IG15TWF0cml4LnNoYXBlXG5cbiMgQ29uc3RydWN0IHNpZ21hIG1hdHJpeCBpbiBTVkRcblNpZyA9IGxpbmFsZy5kaWFnc3ZkKHMsTSxOKSJ9

Ten en cuenta que para matrices dispersas puedes usar sparse.linalg.svds() para realizar la descomposición.

Si eres nuevo en data science, esta descomposición puede resultarte algo opaca: quizá no veas casos de uso inmediatos. Pero la SVD es útil en muchas tareas, como compresión de datos, reducción de ruido y análisis de datos. A continuación verás cómo usar SVD para comprimir imágenes:

# Import the necessary packagesimport numpy as npfrom scipy import linalgfrom skimage import dataimport matplotlib.pyplot as plt# Get an image from `skimage`img= data.camera()# Check number of singular valueslinalg.svdvals(img)# Singular Value DecompositionU, s, Vh = linalg.svd(img)# Use only 32 singular valuesA = np.dot(U[:,0:32],           np.dot(np.diag(s[0:32]), Vh[0:32,:]))fig = plt.figure(figsize=(8, 3))# Add a subplot to the figureax = fig.add_subplot(121)# Plot `img` on grayscaleax.imshow(img, cmap='gray')# Add a second subplot to the figureax2 = fig.add_subplot(122)# Plot `A` in the second subplotax2.imshow(A)# Add a titlefig.suptitle('Image Compression with SVD', fontsize=14, fontweight='bold')# Show the plotplt.show()

Que te dará el siguiente resultado:


image compression with svd

Considera también estos ejemplos donde se usa SVD:

  • La SVD está muy ligada al Análisis de Componentes Principales (PCA), que se usa para la reducción de dimensionalidad: ambos producen un conjunto de «ejes nuevos» construidos a partir de combinaciones lineales de los ejes del espacio de características de tus datos. Estos «ejes nuevos» descomponen la varianza de los puntos en función de la contribución de cada dirección a la varianza. Para ver un ejemplo concreto de cómo funciona PCA en datos, ve a nuestro tutorial de Scikit-Learn.
  • Otro vínculo es con la minería de datos y el procesamiento de lenguaje natural (NLP): Latent Semantic Indexing (LSI). Es una técnica para la recuperación de documentos y la similitud de palabras. El indexing semántico latente usa SVD para agrupar documentos según conceptos que pueden formarse por distintas palabras presentes en esos documentos. Varias palabras pueden agruparse en un concepto. Aquí también, SVD reduce el ruido en la correlación entre palabras y documentos y disminuye el número de dimensiones de los datos originales.

Como ves, la SVD es un concepto importante en tu camino de data science que debes cubrir. Por eso, te recomendamos profundizar más allá de lo que cubre este tutorial: por ejemplo, visita esta página para leer más sobre esta descomposición matricial.

¿Qué viene ahora?

¡Has llegado al final del tutorial! A partir de aquí, el camino lo eliges tú.

¡Pero espera!

No te pierdas los cursos que profundizan en álgebra lineal: este tutorial solo ha sido una introducción y no lo ha cubierto todo.

Por supuesto, considera también hacer el tutorial de machine learning de DataCamp, que aportará mucho a tu programa de formación tras este tutorial de SciPy sobre álgebra lineal. Y si quieres volver a lo básico, repasa nuestro tutorial de NumPy o el curso de Python intermedio para data science.

Temas
Python
Ciencia de datos
Análisis de datos

Aprende más sobre Python

Curso

Python intermedio

4 h
1.4M
Mejora tus conocimientos de ciencia de datos creando visualizaciones con Matplotlib y manipulando DataFrames con pandas.
Ver detallesRight Arrow
Iniciar Curso
Ver másRight Arrow
Relacionado

Tutorial

Tutorial sobre máquinas de vectores de soporte con Scikit-learn

En este tutorial, aprenderás sobre las máquinas de vectores de soporte, uno de los algoritmos de machine learning supervisado más populares y utilizados.
Avinash Navlani's photo

Avinash Navlani

15 min

Tutorial

Tutorial de ecuación normal para regresión lineal

Aprende qué es la ecuación normal y cómo puedes utilizarla para construir modelos de machine learning.
Kurtis Pykes 's photo

Kurtis Pykes

8 min

Tutorial

Arreglos en Python

Arreglos de Python con ejemplos de código. ¡Aprende hoy mismo a crear e imprimir arreglos con Python NumPy!
DataCamp Team's photo

DataCamp Team

3 min

Tutorial

Tutorial de regresión lineal en R

En este tutorial aprenderás los fundamentos de un modelo estadístico muy popular: la regresión lineal.

Eladio Montero Porras

15 min

Tutorial

Optimización en Python: Técnicas, Paquetes y Buenas Prácticas

Este artículo te enseña la optimización numérica, destacando diferentes técnicas. Analiza paquetes de Python como SciPy, CVXPY y Pyomo, y proporciona un práctico cuaderno DataLab para ejecutar ejemplos de código.
Kurtis Pykes 's photo

Kurtis Pykes

11 min

Tutorial

Gráfico lineal de series temporales Matplotlib

Este tutorial explora cómo crear y personalizar gráficos de líneas de series temporales en matplotlib.
Elena Kosourova's photo

Elena Kosourova

8 min

Ver MásVer Más