[Python-es] [Consulta] isin()

Ricardo Cárdenes ricardo.cardenes en gmail.com
Mie Ago 5 16:22:14 EDT 2020


Por cierto, añado: observa que limité los criterios a columnas concretas.
Eso tiene perfecto sentido aquí porque cada columna tiene una semántica
diferente. Sin embargo, nada te impide aplicar isin a un DataFrame entero.
El problema es que el resultado puede no tener mucho sentido (o sí,
depende):

>>> mask = df2.isin(['382.24', '617.12'])
>>> mask
         lab   pami
19     False  False
629    False   True
23549  False  False
30087  False   True


Obviamente, todas las entradas de la columna "lab" salen falsos. ¿Qué
sucede si usas esto como máscara?

>>> df2[mask]
       lab    pami
19     NaN     NaN
629    NaN  382.24
23549  NaN     NaN
30087  NaN  617.12


Dado que no puedes discriminar filas enteras, la máscara no sabe lo que
estás queriendo hacer. Y por tanto va a mostrarte *todo*, pero poniendo
valores NaN ("not a number") en las celdas falsas.

Por cierto, que la máscara no tiene por qué ser un DataSet. Puede ser por
ejemplo una simple lista, que se aplica al primer eje (filas, en este caso):

>>> df2[[False, True, False, True]]
         lab    pami
629    Alcon  382.24
30087  Fabra  617.12


Y dado que Pandas se apoya en NumPy, imagino que puedes pasar un array de
NumPy también.


On Wed, Aug 5, 2020 at 10:12 AM Ricardo Cárdenes <ricardo.cardenes en gmail.com>
wrote:

> Aparte de lo que te está contestando Darío (error en la entrada: 627.12 en
> lugar de 617.12), a tu otra pregunta...
>
> - Acá paso también 2 valores: 1 y 3, no entiendo porque me muestra valores
>> booleanos, en realidad no se que estaría chequeando
>
>
> isin te devuelve *siempre* un DataFrame de booleanos, siendo True las
> celdas donde hay coincidencia con alguno de los valores que pasaste a isin.
> Así pues, ninguna sorpresa. Ese dataframe de booleanos lo puedes utilizar
> como una *máscara* para filtrar los valores de otro DataFrame. Eso es lo
> que haces en tu ejemplo anterior:
>
> *print(df2[df2['pami'].isin(['382.24', '627.12'])])*
>
>
>  Observa que estás usando df2['pami'].isin(['382.24', '627.12']) como
> índice del propio df2. En este caso, tu máscara está discriminando
> algunas filas: el resultado de df2[mascara] será un nuevo DataFrame que
> mostrará (normalmente esto se hace con una clase proxy que actúa como
> "vista") sólo esas filas.
>
> En tu segundo ejemplo no estás aplicando la máscara: la estás imprimiendo
> directamente y por tanto sólo ves los booleanos.
>
> Curiosidad: las máscaras se pueden combinar usando operaciones booleanas
> normales. Por ejemplo, combinando criterios sobre diferentes columnas:
>
> >>> l = df2['lab'].isin(['Alcon'])
> >>> p = df2['pami'].isin(['382.24', '617.12'])
> >>> l
> 19       False
> 629      False
> 23549     True
> 30087    False
> Name: lab, dtype: bool
> >>> p
> 19       False
> 629       True
> 23549    False
> 30087     True
> Name: pami, dtype: bool
> >>> l & p    # AND lógico -> todas False porque no coincide nada
> 19       False
> 629      False
> 23549    False
> 30087    False
> dtype: bool
> >>> l | p    # OR lógico -> combina las filas True de ambas
> 19       False
> 629       True
> 23549     True
> 30087     True
> dtype: bool
> >>> df2[l | p]    # DataFrame con las filas que cumplen AL MENOS uno de
> los dos criterios
>           lab    pami
> 629     Alcon  382.24
> 23549  Duncan  245.44
> 30087   Fabra  617.12
> >>> df2[l & p]    # DataFrame con las filas que cumplen AMBOS criterios
> (está vacío, claro)
> Empty DataFrame
> Columns: [lab, pami]
> Index: []
>
>
> Saludos,
> Ricardo
>
> On Wed, Aug 5, 2020 at 9:06 AM Lemarchand Barker <lemarchand8679 en gmail.com>
> wrote:
>
>> Hola siguiendo con la lectura de pandas, estoy probando isin() y no me
>> queda muy en claro bien que función cumple y qué tipo de uso le podría dar.
>> Mi ejemplo es el siguiente:
>>
>> leer = pd.read_csv('democsv.csv')
>> df = pd.DataFrame({
>>     'lab': ['Abbott Diabetes', 'Alcon', 'Duncan', 'Fabra'],
>>     'pami': ['490.13', '382.24', '245.44', '617.12'],},
>>     index=['19', '629', '23549', '30087'])
>> df2 = df.copy()
>>
>> df2['pami'] = ['490.13', '382.24', '245.44', '617.12']
>> *print(df2['pami'])*
>>
>> Salida:
>> 19       490.13
>> 629      382.24
>> 23549    245.44
>> 30087    617.12
>> Name: pami, dtype: object
>>
>>
>> *print(df2[df2['pami'].isin(['382.24', '627.12'])])*
>>
>> - En esta salida tengo un inconveniente, paso 2 valores: 382.24 y 627.12
>> y solo muestra 1, qué estoy haciendo mal?
>>
>> Salida:
>>            lab    pami
>> 629  Alcon  382.24
>>
>>
>> *print(df2.isin({'pami': [1, 3]}))*
>>
>> - Acá paso también 2 valores: 1 y 3, no entiendo porque me muestra
>> valores booleanos, en realidad no se que estaría chequeando
>>
>> Salida:
>>               lab   pami
>> 19        False  False
>> 629      False  False
>> 23549  False  False
>> 30087  False  False
>>
>> Muchas gracias, saludos
>>
>> _______________________________________________
>> Python-es mailing list
>> Python-es en python.org
>> https://mail.python.org/mailman/listinfo/python-es
>>
>
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://mail.python.org/pipermail/python-es/attachments/20200805/5998642c/attachment.html>


Más información sobre la lista de distribución Python-es