zeros tutorial que matriz matrices libreria inversa funcion español ejemplos array arange python arrays numpy pad

python - tutorial - numpy zeros



Python cómo rellenar una matriz numpy con ceros (4)

En caso de que necesite agregar una cerca de 1s a una matriz:

>>> mat = np.zeros((4,4), np.int32) >>> mat array([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]) >>> mat[0,:] = mat[:,0] = mat[:,-1] = mat[-1,:] = 1 >>> mat array([[1, 1, 1, 1], [1, 0, 0, 1], [1, 0, 0, 1], [1, 1, 1, 1]])

Quiero saber cómo puedo rellenar una matriz numpy 2D con ceros usando python 2.6.6 con la versión numpy 1.5.0. ¡Lo siento! Pero estas son mis limitaciones. Por lo tanto, no puedo usar np.pad . Por ejemplo, quiero rellenar a con ceros de modo que su forma coincida con b . La razón por la que quiero hacer esto es para poder hacer:

b-a

tal que

>>> a array([[ 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1.]]) >>> b array([[ 3., 3., 3., 3., 3., 3.], [ 3., 3., 3., 3., 3., 3.], [ 3., 3., 3., 3., 3., 3.], [ 3., 3., 3., 3., 3., 3.]]) >>> c array([[1, 1, 1, 1, 1, 0], [1, 1, 1, 1, 1, 0], [1, 1, 1, 1, 1, 0], [0, 0, 0, 0, 0, 0]])

La única forma en que puedo pensar en hacer esto es anexar, sin embargo, esto parece bastante feo. ¿Existe una solución más limpia que posiblemente use b.shape ?

Editar, gracias a la respuesta de MSeiferts. Tuve que limpiarlo un poco, y esto es lo que obtuve:

def pad(array, reference_shape, offsets): """ array: Array to be padded reference_shape: tuple of size of ndarray to create offsets: list of offsets (number of elements must be equal to the dimension of the array) will throw a ValueError if offsets is too big and the reference_shape cannot handle the offsets """ # Create an array of zeros with the reference shape result = np.zeros(reference_shape) # Create a list of slices from offset to offset + shape in each dimension insertHere = [slice(offsets[dim], offsets[dim] + array.shape[dim]) for dim in range(array.ndim)] # Insert the array in the result at the specified offsets result[insertHere] = array return result


Entiendo que su principal problema es que necesita calcular d=ba pero sus matrices tienen diferentes tamaños. No hay necesidad de un acolchado intermedio c

Puede resolver esto sin relleno:

import numpy as np a = np.array([[ 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1.]]) b = np.array([[ 3., 3., 3., 3., 3., 3.], [ 3., 3., 3., 3., 3., 3.], [ 3., 3., 3., 3., 3., 3.], [ 3., 3., 3., 3., 3., 3.]]) d = b.copy() d[:a.shape[0],:a.shape[1]] -= a print d

Salida:

[[ 2. 2. 2. 2. 2. 3.] [ 2. 2. 2. 2. 2. 3.] [ 2. 2. 2. 2. 2. 3.] [ 3. 3. 3. 3. 3. 3.]]


Muy simple, crea una matriz que contiene ceros utilizando la forma de referencia:

result = np.zeros(b.shape) # actually you can also use result = np.zeros_like(b) # but that also copies the dtype not only the shape

y luego inserte la matriz donde la necesite:

result[:a.shape[0],:a.shape[1]] = a

y listo lo has rellenado:

print(result) array([[ 1., 1., 1., 1., 1., 0.], [ 1., 1., 1., 1., 1., 0.], [ 1., 1., 1., 1., 1., 0.], [ 0., 0., 0., 0., 0., 0.]])

También puede hacerlo un poco más general si define dónde se debe insertar su elemento superior izquierdo

result = np.zeros_like(b) x_offset = 1 # 0 would be what you wanted y_offset = 1 # 0 in your case result[x_offset:a.shape[0]+x_offset,y_offset:a.shape[1]+y_offset] = a result array([[ 0., 0., 0., 0., 0., 0.], [ 0., 1., 1., 1., 1., 1.], [ 0., 1., 1., 1., 1., 1.], [ 0., 1., 1., 1., 1., 1.]])

pero luego tenga cuidado de no tener compensaciones más grandes de lo permitido. Para x_offset = 2 por ejemplo, esto fallará.

Si tiene un número arbitrario de dimensiones, puede definir una lista de sectores para insertar la matriz original. Me pareció interesante jugar un poco y creé una función de relleno que puede rellenar (con desplazamiento) una matriz de forma arbitraria siempre que la matriz y la referencia tengan el mismo número de dimensiones y los desplazamientos no sean demasiado grandes.

def pad(array, reference, offsets): """ array: Array to be padded reference: Reference array with the desired shape offsets: list of offsets (number of elements must be equal to the dimension of the array) """ # Create an array of zeros with the reference shape result = np.zeros(reference.shape) # Create a list of slices from offset to offset + shape in each dimension insertHere = [slice(offset[dim], offset[dim] + array.shape[dim]) for dim in range(a.ndim)] # Insert the array in the result at the specified offsets result[insertHere] = a return result

Y algunos casos de prueba:

import numpy as np # 1 Dimension a = np.ones(2) b = np.ones(5) offset = [3] pad(a, b, offset) # 3 Dimensions a = np.ones((3,3,3)) b = np.ones((5,4,3)) offset = [1,0,0] pad(a, b, offset)


NumPy 1.7.0 (cuando se agregó numpy.pad ) es bastante antiguo ahora (se lanzó en 2013), así que aunque la pregunta solicitó una forma sin usar esa función, pensé que podría ser útil saber cómo se podría lograr eso usando numpy.pad .

En realidad es bastante simple:

>>> import numpy as np >>> a = np.array([[ 1., 1., 1., 1., 1.], ... [ 1., 1., 1., 1., 1.], ... [ 1., 1., 1., 1., 1.]]) >>> np.pad(a, [(0, 1), (0, 1)], mode=''constant'') array([[ 1., 1., 1., 1., 1., 0.], [ 1., 1., 1., 1., 1., 0.], [ 1., 1., 1., 1., 1., 0.], [ 0., 0., 0., 0., 0., 0.]])

En este caso, utilicé que 0 es el valor predeterminado para mode=''constant'' . Pero también podría especificarse pasándolo explícitamente:

>>> np.pad(a, [(0, 1), (0, 1)], mode=''constant'', constant_values=0) array([[ 1., 1., 1., 1., 1., 0.], [ 1., 1., 1., 1., 1., 0.], [ 1., 1., 1., 1., 1., 0.], [ 0., 0., 0., 0., 0., 0.]])

En caso de que el segundo argumento ( [(0, 1), (0, 1)] ) parezca confuso: cada elemento de la lista (en este caso, la tupla) corresponde a una dimensión y el elemento en él representa el relleno antes (primer elemento) y después (segundo elemento). Entonces:

[(0, 1), (0, 1)] ^^^^^^------ padding for second dimension ^^^^^^-------------- padding for first dimension ^------------------ no padding at the beginning of the first axis ^--------------- pad with one "value" at the end of the first axis.

En este caso, el relleno para el primer y el segundo eje son idénticos, por lo que también se podría pasar la tupla de 2:

>>> np.pad(a, (0, 1), mode=''constant'') array([[ 1., 1., 1., 1., 1., 0.], [ 1., 1., 1., 1., 1., 0.], [ 1., 1., 1., 1., 1., 0.], [ 0., 0., 0., 0., 0., 0.]])

En caso de que el relleno antes y después sea idéntico, incluso podría omitirse la tupla (aunque no es aplicable en este caso):

>>> np.pad(a, 1, mode=''constant'') array([[ 0., 0., 0., 0., 0., 0., 0.], [ 0., 1., 1., 1., 1., 1., 0.], [ 0., 1., 1., 1., 1., 1., 0.], [ 0., 1., 1., 1., 1., 1., 0.], [ 0., 0., 0., 0., 0., 0., 0.]])

O si el relleno antes y después es idéntico pero diferente para el eje, también puede omitir el segundo argumento en las tuplas internas:

>>> np.pad(a, [(1, ), (2, )], mode=''constant'') array([[ 0., 0., 0., 0., 0., 0., 0., 0., 0.], [ 0., 0., 1., 1., 1., 1., 1., 0., 0.], [ 0., 0., 1., 1., 1., 1., 1., 0., 0.], [ 0., 0., 1., 1., 1., 1., 1., 0., 0.], [ 0., 0., 0., 0., 0., 0., 0., 0., 0.]])

Sin embargo, tiendo a preferir usar siempre el explícito, porque es muy fácil cometer errores (cuando las expectativas de NumPys difieren de sus intenciones):

>>> np.pad(a, [1, 2], mode=''constant'') array([[ 0., 0., 0., 0., 0., 0., 0., 0.], [ 0., 1., 1., 1., 1., 1., 0., 0.], [ 0., 1., 1., 1., 1., 1., 0., 0.], [ 0., 1., 1., 1., 1., 1., 0., 0.], [ 0., 0., 0., 0., 0., 0., 0., 0.], [ 0., 0., 0., 0., 0., 0., 0., 0.]])

¡Aquí NumPy cree que quería rellenar todos los ejes con 1 elemento antes y 2 elementos después de cada eje! Incluso si pretendía rellenar con 1 elemento en el eje 1 y 2 elementos para el eje 2.

Usé listas de tuplas para el relleno, tenga en cuenta que esto es solo "mi convención", también podría usar listas de listas o tuplas de tuplas, o incluso tuplas de matrices. ¡NumPy solo comprueba la longitud del argumento (o si no tiene una longitud) y la longitud de cada elemento (o si tiene una longitud)!