Numpy II

En la entrada anterior, Numpy I, realicé una presentación de la librería Numpy y realicé la descripción de unos ejemplos básicos. En la presenta entrada, Numpy II, continuaré presentando ejemplos de operaciones con la Numpy.

Los ejemplos de utilización de la librería Numpy a presentar en esta entrada son los siguientes:

  1. Operaciones de arrays con sus dimensiones.
  2. Indexación avanzada.
  3. Operaciones de comparación.

1.- Operaciones de arrays con sus dimensiones.

Los arrays son estructuras n-dimensionales con los cuáles podemos realizar sumas a pesar de tener diferente número de dimensión. A continuación, muestro una serie de ejemplos.

Sean dos arrays con la misma dimensión y número de elementos por dimensión, la operación suma se realiza con el operador +. El snippet del código es el siguiente:

array1 = np.array([1, 2, 3])
array2 = np.array([4, 5, 6])
print(f'array1 + array2={array1 + array2}')

La salida por consola es la siguiente:

array1 + array2=[5 7 9]

Sea un array de dos dimenciones con tres elementos por dimensión y un array de una dimensión e igual número de elementos que el primero. El snippet del código es el siguiente:

array3 = np.array([[7, 8, 9], [3, 2, 1]])
print(f'array3 + array1={array3 + array1}')

La salida por consola es la siguiente:

array3 + array1=[[ 8 10 12]
 [ 4  4  4]]

Sea un array de dos dimensiones con tres elementos y un array de dos dimensiones de un elemento por dimensión. El resultado es una array de dos dimensiones de tres elementos en el que se ha incrementado el valor del segundo array. El snippet del código es el siguiente:

array_21 = np.array([[1], [2]])
print(f'array3 + array_21={array3 + array_21}')  

La salida por consola es la siguiente:

array3 + array_21=[[ 8  9 10]
 [ 5  4  3]]

2.- Indexación avanzada.

Para realizar operaciones con parte de los elmentos de un array, se deben de crear referencias a la estructura con la que se desea operar. Si se desea incrementar en 100 la segunda posición de las dimensiones que forman parte de un array, se crea una referencia a las posiciones de todas las dimensiones y se incrementa en 100 con el operador +=, en nuestro ejemplo, center_array; una vez operado, el array inicial contiene el resultado. Hay que destacar que las operaciones no son inmutables y se trabaja con referencias. El snippet del código es el siguiente:

array = np.array([[1, 2, 3], [4, 5, 6]])
center_array = array[:, 1]
center_array += 100
print(f'center_array=\n{center_array}')
print(f'array=\n{array}')

La salida por consola es la siguiente:

center_array=
[102 105]
array=
[[  1 102   3]
 [  4 105   6]]

Si se desea realizar una copia de una dimensión se utiliza la función copy. En el siguiente ejemplo, se realiza una copia de una dimensión de una array inicial. El snippet de ejemplo es el siguiente:

array2 = np.array([[1, 2, 3], [4, 5, 6]])
second_row = array2[1].copy()  
second_row += 100
print(f'second_row=\n{second_row}')
print(f'array2=\n{array2}')

La salida por consola es la siguiente:

second_row=
[104 105 106]
array2=
[[1 2 3]
 [4 5 6]]

Para determinar si una referencia es una copia o forma parte de una estructura se emplea la función may_share_memory. A continuación, se muestran dos ejemplos de ejemplos previos. El snippet de código es el siguiente:

  first_row = array2[:1]
  np.may_share_memory(first_row, array2)
  print(f'np.may_share_memory(first_row, array2)=\n{np.may_share_memory(first_row, array2)}')
  print(f'np.may_share_memory(second_row, array2)=\n{np.may_share_memory(second_row, array2)}')

La salida por consola es la siguiente:

  np.may_share_memory(first_row, array2)=
  True
  np.may_share_memory(second_row, array2)=
  False

Para obtener arrays que sean subconjuntos de un array, podemos realizar seleccion de posiciones de una determinada dimensión. En el siguiente ejemplo, se imprimen todos los elementos de la primera dimensión y el primer y último elemento de la segundo; y, por último, el caso contrario, último y primero. El snippet del código es el siguiente:

array3 = np.array([[1, 2, 3], [4, 5, 6]])
print(f'array3=\n{array3}')  
print(f'array3[:, [0,2]]=\n{array3[:, [0,2]]}')  
print(f'array3[:, [2,0]]=\n{array3[:, [2,0]]}')  

La salida por consola es la siguiente:

array3=
[[1 2 3]
 [4 5 6]]
array3[:, [0,2]]=
[[1 3]
 [4 6]]
array3[:, [2,0]]=
[[3 1]
 [6 4]]

Por último, se pueden realizar operaciones de comparación de los elementos y obtener array lógicos con el resultado. En el siguiente ejemplo, se imprimen los elementos mayores a 3; impresión de los elementos que son mayores a 3; y, por último, se compone un predicado lógico. El snippet del código es el siiguiente:

array3 = np.array([[1, 2, 3], [4, 5, 6]])
print(f'array3 > 3=\n{array3 > 3}')  
print(f'array3[array3 > 3]=\n{array3[array3 > 3]}')  
print(f'array3[(array3 > 2) & (array3 <5)]=\n{array3[(array3 > 2) & (array3 <5)]}')

La salida por consola es la siguiente:

array3 > 3=
[[False False False]
 [ True  True  True]]
array3[array3 > 3]=
[4 5 6]
array3[(array3 > 2) & (array3 <5)]=
[3 4]

3.- Operaciones de comparación.

En el apartado anterior, se presentó la operación de comparación y, en el presente apartado, profundizaremos en las operaciones de comparación. En este primer ejemplo, se muestra una selección de elementos de un array mayores a 2. El snippet del código es el siguiente:

array = np.array([1, 2, 3, 4])
array_mayor_2 = array > 2
print(f'array_mayor_2=\n{array_mayor_2}\n')

La salida por consola es la siguiente:

array_mayor_2=
[False False  True  True]

Con los resultados lógicos podemos realizar operaciones para poder operar con ellos. Para ello, podemos emplear las siguientes funciones:

  • Función sum.- función que cuantifica el número de elementos que cumplen la función.
  • Función nonzero.- función que retorna el índice de la posición en la dimensión.

En el siguiente snippet se muestran ejemplos a partir del array inicial:

print(f'array[array_mayor_2]=\n{array[array_mayor_2]}\n')
print(f'array_mayor_2.sum()=\n{array_mayor_2.sum()}\n')  
print(f'array_mayor_2.nonzero()=\n{array_mayor_2.nonzero()}\n')  
print(f'(array > 2).nonzero()=\n{(array > 2).nonzero()}\n')  

La salida por consola es la siguiente:

array[array_mayor_2]=
[3 4]

array_mayor_2.sum()=
 2

array_mayor_2.nonzero()=
(array([2, 3]),)

(array > 2).nonzero()=
(array([2, 3]),)

Para poder realizar un tratamiento más específico, podemos utilizar la función where en la cuál podemos declarar qué valor asignar al resultado si cumple una condición, o bien, cuando no la cumple. En el siguiente snippet se muestra un ejemplo de uso de la función where:

array_where = np.where(array > 2)
print(f'np.where(array > 2)=\n{array_where}\n')
array_where_2 = np.where(array > 2, 1, 0)  
print(f'np.where(array > 2, 1, 0)=\n{array_where_2}\n')

La salida por consola es la siguiente:

 np.where(array > 2)=
  (array([2, 3]),)

  np.where(array > 2, 1, 0)=
  [0 0 1 1]

Otra forma de trabajar con predicados sin la función where es declarando un predicado con una condición. Una vez creado el predicado, lo aplicamos en el array como una indexación asignando el valor para el caso de éxito, o bien, utilizando el carácter ~ para el caso de no cumplirse. En el siguiente snippet se muestra un ejemplo de uso de ejemplo:

array2 = np.array([1, 2, 3, 4])
array2_mayor_2 = array2 > 2
array2[array2_mayor_2] = 1  
array2[~array2_mayor_2] = 0  
print(f'array2={array2}')

La salida por consola es la siguiente:

array2=[0 0 1 1]

En la siguiente entrada con título Numpy III presentaré los últimos ejemplos y finalizaré la serie de entradas relacionadas con la librería Numpy.

Un comentario en “Numpy II

Deja un comentario