Introducción a NumPy¶

Numpy es una librería fundamental para la computación científica con Python.

  • Proporciona arrays N-dimensionales
  • Implementa funciones matemáticas sofisticadas
  • Proporciona herramientas para integrar C/C++ y Fortran
  • Proporciona mecanismos para facilitar la realización de tareas relacionadas con álgebra lineal o números aleatorios

Imports¶

In [1]:
import numpy as np

Arrays¶

Un array es una estructura de datos que consiste en una colección de elementos (valores o variables), cada uno identificado por al menos un índice o clave. Un array se almacena de modo que la posición de cada elemento se pueda calcular a partir de su tupla de índice mediante una fórmula matemática. El tipo más simple de array es un array lineal, también llamado array unidimensional.

En numpy:

  • Cada dimensión se denomina axis
  • El número de dimensiones se denomina rank
  • La lista de dimensiones con su correspondiente longitud se denomina shape
  • El número total de elementos (multiplicación de la longitud de las dimensiones) se denomina size
In [2]:
# Array cuyos valores son todos 0
a = np.zeros((2, 4))
In [3]:
a
Out[3]:
array([[0., 0., 0., 0.],
       [0., 0., 0., 0.]])

a es un array:

  • Con dos axis, el primero de longitud 2 y el segundo de longitud 4
  • Con un rank igual a 2
  • Con un shape igual (2, 4)
  • Con un size igual a 8
In [4]:
a.shape
Out[4]:
(2, 4)
In [5]:
a.ndim
Out[5]:
2
In [6]:
a.size
Out[6]:
8

Creación de Arrays¶

In [7]:
# Array cuyos valores son todos 0
np.zeros((2, 3, 4))
Out[7]:
array([[[0., 0., 0., 0.],
        [0., 0., 0., 0.],
        [0., 0., 0., 0.]],

       [[0., 0., 0., 0.],
        [0., 0., 0., 0.],
        [0., 0., 0., 0.]]])
In [8]:
# Array cuyos valores son todos 1
np.ones((2, 3, 4))
Out[8]:
array([[[1., 1., 1., 1.],
        [1., 1., 1., 1.],
        [1., 1., 1., 1.]],

       [[1., 1., 1., 1.],
        [1., 1., 1., 1.],
        [1., 1., 1., 1.]]])
In [9]:
# Array cuyos valores son todos el valor indicado como segundo parámetro de la función
np.full((2, 3, 4), 8)
Out[9]:
array([[[8, 8, 8, 8],
        [8, 8, 8, 8],
        [8, 8, 8, 8]],

       [[8, 8, 8, 8],
        [8, 8, 8, 8],
        [8, 8, 8, 8]]])
In [10]:
# El resultado de np.empty no es predecible 
# Inicializa los valores del array con lo que haya en memoria en ese momento
np.empty((2, 3, 9))
Out[10]:
array([[[2.68156159e+154, 2.68156159e+154, 1.38338381e-322,
         0.00000000e+000, 0.00000000e+000, 0.00000000e+000,
         0.00000000e+000, 0.00000000e+000, 0.00000000e+000],
        [0.00000000e+000, 0.00000000e+000, 0.00000000e+000,
         0.00000000e+000, 0.00000000e+000, 0.00000000e+000,
         0.00000000e+000, 0.00000000e+000, 0.00000000e+000],
        [0.00000000e+000, 0.00000000e+000, 0.00000000e+000,
         0.00000000e+000, 0.00000000e+000, 0.00000000e+000,
         0.00000000e+000, 0.00000000e+000, 0.00000000e+000]],

       [[0.00000000e+000, 0.00000000e+000, 0.00000000e+000,
         0.00000000e+000, 0.00000000e+000, 0.00000000e+000,
         0.00000000e+000, 0.00000000e+000, 0.00000000e+000],
        [0.00000000e+000, 0.00000000e+000, 0.00000000e+000,
         0.00000000e+000, 0.00000000e+000, 0.00000000e+000,
         0.00000000e+000, 0.00000000e+000, 0.00000000e+000],
        [4.94065646e-324, 4.94065646e-324, 0.00000000e+000,
         0.00000000e+000, 2.19183626e-314, 0.00000000e+000,
         0.00000000e+000, 0.00000000e+000, 2.19183624e-314]]])
In [11]:
# Inicializacion del array utilizando un array de Python
b = np.array([[1, 2, 3], [4, 5, 6]])
b
Out[11]:
array([[1, 2, 3],
       [4, 5, 6]])
In [12]:
b.shape
Out[12]:
(2, 3)
In [13]:
# Creación del array utilizando una función basada en rangos
# (minimo, maximo, número elementos del array)
print(np.linspace(0, 6, 10))
[0.         0.66666667 1.33333333 2.         2.66666667 3.33333333
 4.         4.66666667 5.33333333 6.        ]
In [14]:
# Inicialización del array con valores aleatorios
np.random.rand(2, 3, 4)
Out[14]:
array([[[0.86112367, 0.38424412, 0.1374698 , 0.00374164],
        [0.17986908, 0.70623686, 0.79187786, 0.55727964],
        [0.35682263, 0.3653425 , 0.46985688, 0.21260774]],

       [[0.5880182 , 0.95377117, 0.5725985 , 0.61780224],
        [0.87126124, 0.69692227, 0.30400387, 0.98945466],
        [0.79692312, 0.42435095, 0.39549556, 0.21133076]]])
In [15]:
# Inicialización del array con valores aleatorios conforme a una distribución normal
np.random.randn(2, 4)
Out[15]:
array([[ 0.23938   , -1.32113218, -0.27591314, -1.00013485],
       [-0.21246352,  0.01347011,  0.16525681,  1.82440834]])
In [16]:
%  matplotlib inline
import matplotlib.pyplot as plt

c = np.random.randn(1000000)

plt.hist(c, bins=200)
plt.show()
In [17]:
# Inicialización del Array utilizando una función personalizada

def func(x, y):
    return x + 2 * y

np.fromfunction(func, (3, 5))
Out[17]:
array([[ 0.,  2.,  4.,  6.,  8.],
       [ 1.,  3.,  5.,  7.,  9.],
       [ 2.,  4.,  6.,  8., 10.]])

Acceso a los elementos de un array¶

Array unidimensional¶

In [18]:
# Creación de un Array unidimensional
array_uni = np.array([1, 3, 5, 7, 9, 11])
print("Shape:", array_uni.shape)
print("Array_uni:", array_uni)
Shape: (6,)
Array_uni: [ 1  3  5  7  9 11]
In [19]:
# Accediendo al quinto elemento del Array
array_uni[4]
Out[19]:
9
In [20]:
# Accediendo al tercer y cuarto elemento del Array
array_uni[2:4]
Out[20]:
array([5, 7])
In [22]:
# Accediendo a los elementos 0, 3 y 5 del Array
array_uni[0::3]
Out[22]:
array([1, 7])

Array multidimensional¶

In [23]:
# Creación de un Array multidimensional
array_multi = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
print("Shape:", array_multi.shape)
print("Array_multi:\n", array_multi)
Shape: (2, 4)
Array_multi:
 [[1 2 3 4]
 [5 6 7 8]]
In [24]:
# Accediendo al cuarto elemento del Array
array_multi[0, 3]
Out[24]:
4
In [25]:
# Accediendo a la segunda fila del Array
array_multi[1, :]
Out[25]:
array([5, 6, 7, 8])
In [26]:
# Accediendo al tercer elemento de las dos primeras filas del Array
array_multi[0:2, 2]
Out[26]:
array([3, 7])

Modificación de un Array¶

In [27]:
# Creación de un Array unidimensional inicializado con el rango de elementos 0-27
array1 = np.arange(28)
print("Shape:", array1.shape)
print("Array 1:", array1)
Shape: (28,)
Array 1: [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 24 25 26 27]
In [28]:
# Cambiar las dimensiones del Array y sus longitudes
array1.shape = (7, 4)
print("Shape:", array1.shape)
print("Array 1:\n", array1)
Shape: (7, 4)
Array 1:
 [[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [12 13 14 15]
 [16 17 18 19]
 [20 21 22 23]
 [24 25 26 27]]
In [29]:
# El ejemplo anterior devuelve un nuevo Array que apunta a los mismos datos. 
# Importante: Modificaciones en un Array, modificaran el otro Array
array2 = array1.reshape(4, 7)
print("Shape:", array2.shape)
print("Array 2:\n", array2)
Shape: (4, 7)
Array 2:
 [[ 0  1  2  3  4  5  6]
 [ 7  8  9 10 11 12 13]
 [14 15 16 17 18 19 20]
 [21 22 23 24 25 26 27]]
In [30]:
# Modificación del nuevo Array devuelto
array2[0, 3] = 20
print("Array 2:\n", array2)
Array 2:
 [[ 0  1  2 20  4  5  6]
 [ 7  8  9 10 11 12 13]
 [14 15 16 17 18 19 20]
 [21 22 23 24 25 26 27]]
In [31]:
print("Array 1:\n", array1)
Array 1:
 [[ 0  1  2 20]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [12 13 14 15]
 [16 17 18 19]
 [20 21 22 23]
 [24 25 26 27]]
In [32]:
# Desenvuelve el Array, devolviendo un nuevo Array de una sola dimension
# Importante: El nuevo array apunta a los mismos datos
print("Array 1:", array1.ravel())
Array 1: [ 0  1  2 20  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 24 25 26 27]

Operaciones aritméticas con Arrays¶

In [33]:
# Creación de dos Arrays unidimensionales
array1 = np.arange(2, 18, 2)
array2 = np.arange(8)
print("Array 1:", array1)
print("Array 2:", array2)
Array 1: [ 2  4  6  8 10 12 14 16]
Array 2: [0 1 2 3 4 5 6 7]
In [34]:
# Suma
print(array1 + array2)
[ 2  5  8 11 14 17 20 23]
In [35]:
# Resta
print(array1 - array2)
[2 3 4 5 6 7 8 9]
In [36]:
# Multiplicacion
# Importante: No es una multiplicación de matrices
print(array1 * array2)
[  0   4  12  24  40  60  84 112]

Broadcasting¶

Si se aplican operaciones aritméticas sobre Arrays que no tienen la misma forma (shape) Numpy aplica un propiedad que se denomina Broadcasting.

In [37]:
# Creación de dos Arrays unidimensionales
array1 = np.arange(5)
array2 = np.array([3])
print("Shape Array 1:", array1.shape)
print("Array 1:", array1)
print()
print("Shape Array 2:", array2.shape)
print("Array 2:", array2)
Shape Array 1: (5,)
Array 1: [0 1 2 3 4]

Shape Array 2: (1,)
Array 2: [3]
In [38]:
# Suma de ambos Arrays
array1 + array2
Out[38]:
array([3, 4, 5, 6, 7])
In [39]:
# Creación de dos Arrays multidimensional y unidimensional
array1 = np.arange(6)
array1.shape = (2, 3)
array2 = np.arange(6, 18, 4)
print("Shape Array 1:", array1.shape)
print("Array 1:\n", array1)
print()
print("Shape Array 2:", array2.shape)
print("Array 2:", array2)
Shape Array 1: (2, 3)
Array 1:
 [[0 1 2]
 [3 4 5]]

Shape Array 2: (3,)
Array 2: [ 6 10 14]
In [40]:
# Suma de ambos Arrays
array1 + array2
Out[40]:
array([[ 6, 11, 16],
       [ 9, 14, 19]])

Funciones estadísticas sobre Arrays¶

In [41]:
# Creación de un Array unidimensional
array1 = np.arange(1, 20, 2)
print("Array 1:", array1)
Array 1: [ 1  3  5  7  9 11 13 15 17 19]
In [42]:
# Media de los elementos del Array
array1.mean()
Out[42]:
10.0
In [43]:
# Suma de los elementos del Array
array1.sum()
Out[43]:
100

Funciones universales eficientes proporcionadas por numpy: ufunc

In [44]:
# Cuadrado de los elementos del Array
np.square(array1)
Out[44]:
array([  1,   9,  25,  49,  81, 121, 169, 225, 289, 361])
In [45]:
# Raiz cuadrada de los elementos del Array
np.sqrt(array1)
Out[45]:
array([1.        , 1.73205081, 2.23606798, 2.64575131, 3.        ,
       3.31662479, 3.60555128, 3.87298335, 4.12310563, 4.35889894])
In [46]:
# Exponencial de los elementos del Array
np.exp(array1)
Out[46]:
array([2.71828183e+00, 2.00855369e+01, 1.48413159e+02, 1.09663316e+03,
       8.10308393e+03, 5.98741417e+04, 4.42413392e+05, 3.26901737e+06,
       2.41549528e+07, 1.78482301e+08])
In [47]:
# log de los elementos del Array
np.log(array1)
Out[47]:
array([0.        , 1.09861229, 1.60943791, 1.94591015, 2.19722458,
       2.39789527, 2.56494936, 2.7080502 , 2.83321334, 2.94443898])
In [ ]: