Compruebe si los valores en un conjunto están en una matriz numpy en python

Quiero verificar si un NumPyArray tiene valores que están en un conjunto, y si es así, configure esa área en una matriz = 1. Si no, configure un keepRaster = 2.

numpyArray = #some imported array
repeatSet= ([3, 5, 6, 8])

confusedRaster = numpyArray[numpy.where(numpyArray in repeatSet)]= 1

Rendimientos:

<type 'exceptions.TypeError'>: unhashable type: 'numpy.ndarray'

¿Hay alguna manera de recorrerlo?

 for numpyArray
      if numpyArray in repeatSet
           confusedRaster = 1
      else
           keepRaster = 2

Para aclarar y pedir un poco más de ayuda:

A lo que estoy tratando de llegar, y lo que estoy haciendo actualmente, es poner una entrada de trama en una matriz. Necesito leer valores en la matriz 2-d y crear otra matriz basada en esos valores. Si el valor de la matriz está en un conjunto, el valor será 1. Si no está en un conjunto, el valor se derivará de otra entrada, pero diré 77 por ahora. Esto es lo que estoy usando actualmente. Mi entrada de prueba tiene alrededor de 1500 filas y 3500 columnas. Siempre se congela alrededor de la fila 350.

for rowd in range(0, width):
    for cold in range (0, height):
        if numpyarray.item(rowd,cold) in repeatSet:
            confusedArray[rowd][cold] = 1
        else:
            if numpyarray.item(rowd,cold) == 0:
                confusedArray[rowd][cold] = 0
            else:
                confusedArray[rowd][cold] = 2

preguntado el 21 de mayo de 12 a las 19:05

3 Respuestas

En las versiones 1.4 y posteriores, numpy proporciona la in1d función.

>>> test = np.array([0, 1, 2, 5, 0])
>>> states = [0, 2]
>>> np.in1d(test, states)
array([ True, False,  True, False,  True], dtype=bool)

Puede usar eso como una máscara para la asignación.

>>> test[np.in1d(test, states)] = 1
>>> test
array([1, 1, 1, 5, 1])

Aquí hay algunos usos más sofisticados de la indexación y la sintaxis de asignación de numpy que creo que se aplicarán a su problema. Tenga en cuenta el uso de operadores bit a bit para reemplazar iflógica basada en:

>>> numpy_array = numpy.arange(9).reshape((3, 3))
>>> confused_array = numpy.arange(9).reshape((3, 3)) % 2
>>> mask = numpy.in1d(numpy_array, repeat_set).reshape(numpy_array.shape)
>>> mask
array([[False, False, False],
       [ True, False,  True],
       [ True, False,  True]], dtype=bool)
>>> ~mask
array([[ True,  True,  True],
       [False,  True, False],
       [False,  True, False]], dtype=bool)
>>> numpy_array == 0
array([[ True, False, False],
       [False, False, False],
       [False, False, False]], dtype=bool)
>>> numpy_array != 0
array([[False,  True,  True],
       [ True,  True,  True],
       [ True,  True,  True]], dtype=bool)
>>> confused_array[mask] = 1
>>> confused_array[~mask & (numpy_array == 0)] = 0
>>> confused_array[~mask & (numpy_array != 0)] = 2
>>> confused_array
array([[0, 2, 2],
       [1, 2, 1],
       [1, 2, 1]])

Otro enfoque sería utilizar numpy.where, que crea una nueva matriz, usando valores del segundo argumento donde mask es verdadero, y los valores del tercer argumento donde mask Es falso. (Al igual que con la asignación, el argumento puede ser un escalar o una matriz de la misma forma que mask.) Esto podría ser un poco más eficiente que lo anterior, y ciertamente es más conciso:

>>> numpy.where(mask, 1, numpy.where(numpy_array == 0, 0, 2))
array([[0, 2, 2],
       [1, 2, 1],
       [1, 2, 1]])

contestado el 22 de mayo de 12 a las 21:05

Hmm, así como lo entiendo. Si el valor de la prueba está en la lista de estados que True, que será = 1, de lo contrario será igual a lo que era. ¿Hay alguna manera de hacer que la matriz de salida ([1,0,1,0,0]) - mkmitchell

@mkmitchell, sí, lo tienes. Es algo similar a la asignación de segmentos con las listas normales de Python, pero a) usa el sistema de indexación más complejo de numpy, yb) sigue la convención numpy de que asignar un escalar a un segmento de una matriz asigna todos los valores en el segmento a ese valor escalar. - remitente

¿Qué tal si es una matriz 2-D? - mkmitchell

@mkmitchell, debería funcionar de manera idéntica siempre que la máscara booleana tenga la misma forma que la matriz original. - remitente

@mkmitchell, mirando el resultado de in1d cuando se usa en una matriz 2-d, veo que debe reshape antes de indexar una matriz bidimensional. En otras palabras, si test = np.arange(25).reshape((5, 5)) luego (test[np.in1d(test, states).reshape(test.shape)] == np.array([0, 2])).all() == True. - remitente

Aquí hay una forma posible de hacer lo que quieres:

numpyArray = np.array([1, 8, 35, 343, 23, 3, 8]) # could be n-Dimensional array
repeatSet = np.array([3, 5, 6, 8])
mask = (numpyArray[...,None] == repeatSet[None,...]).any(axis=-1) 
print mask
>>> [False  True False False False  True  True]

contestado el 21 de mayo de 12 a las 19:05

En numpy podrías usar una combinación de np.isin y np.where para lograr este resultado. El primer método genera una matriz numpy booleana que se evalúa como True donde sus valores son iguales a un elemento de prueba especificado similar a una matriz (ver doctor), mientras que con el segundo podría crear una nueva matriz que establezca un valor en el que la configuración especificada se evalúe como True y otro valor donde False.

Ejemplo

Haré un ejemplo con una matriz aleatoria pero usando los valores específicos que proporcionó.

import numpy as np

repeatSet = ([2, 5, 6, 8])

arr = np.array([[1,5,1],
                [0,1,0],
                [0,0,0],
                [2,2,2]])

out = np.where(np.isin(arr, repeatSet), 1, 77)

> out
array([[77,  1, 77],
       [77, 77, 77],
       [77, 77, 77],
       [ 1,  1,  1]])

Respondido el 06 de enero de 21 a las 21:01

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.