Tengo un pandas Series objeto que contiene los valores booleanos. ¿Cómo puedo obtener una serie que contiene la lógica NOT de cada valor?

Por ejemplo, considere la posibilidad de una serie que contiene:

True
True
True
False

La serie que me gustaría conseguir, que contendrá:

False
False
False
True

Este parece que debería ser bastante simple, pero al parecer me he extraviado mi mojo =(

  • Es importante que los datos no contienen object de los tipos de respuestas que figuran a continuación para el trabajo, a fin de utilizar: ~ df.astype('bool')
  • He escrito sobre todo de los operadores lógicos en este post. El post también incluye alternativas.
InformationsquelleAutor blz | 2013-04-14

4 Comentarios

  1. 210

    A invertir un valor booleano de la Serie, usar ~s:

    In [7]: s = pd.Series([True, True, False, True])
    
    In [8]: ~s
    Out[8]: 
    0    False
    1    False
    2     True
    3    False
    dtype: bool

    El Uso De Python2.7, NumPy 1.8.0, Pandas 0.13.1:

    In [119]: s = pd.Series([True, True, False, True]*10000)
    
    In [10]:  %timeit np.invert(s)
    10000 loops, best of 3: 91.8 µs per loop
    
    In [11]: %timeit ~s
    10000 loops, best of 3: 73.5 µs per loop
    
    In [12]: %timeit (-s)
    10000 loops, best of 3: 73.5 µs per loop

    Como de los Pandas 0.13.0, la Serie no son subclases de numpy.ndarray; ahora son subclases de pd.NDFrame. Esto podría tener algo que ver con el por qué np.invert(s) ya no es tan rápido como ~s o -s.

    Advertencia: timeit los resultados pueden variar dependiendo de muchos factores, incluyendo el hardware, el compilador, sistema operativo, Python, NumPy y Pandas versiones.

    • Debidamente comprobada. Aparte de ser mucho más lento, ¿cuál es la diferencia entre la tilde y - ?
    • Raro, he probado la tilde como se menciona en la documentación, pero no realizan la misma como np.invert :S
    • Al menos en mi máquina de Ubuntu, la ejecución de NumPy 1.6.2, el rendimiento de np.invert(s), ~s y -s son todos de la misma.
    • No estoy seguro de por qué existe una gran discrepancia en nuestro timeit los resultados, sino que ciertamente puede suceder. Qué sistema operativo y versión de NumPy estás usando?
    • También en Ubuntu, pero el uso de NumPy 1.7.0…(np.bitwise_not(s) realiza la misma como np.inverse).
    • Puedo confirmar que np.invert y la ~ operador tienen idéntico rendimiento de mi máquina así: numpy 1.6.2 en Ubuntu última.
    • ¿De dónde los Pandas documentación decir acerca de la ~ operador?
    • Se menciona aquí.

  2. 18

    @unutbu la respuesta está en el lugar, sólo quería añadir una advertencia de que la máscara debe ser dtype bool, no ‘objeto’. Es decir que su máscara no puede tener nunca tenido alguna de nan. Ver aquí – incluso si la máscara es nan-gratis ahora, seguirá siendo «objeto» de tipo.

    El inverso de un «objeto» de la serie no tiro un error, en lugar obtendrá un cubo de basura de la máscara de enteros que no funcionan como se espera.

    In[1]: df = pd.DataFrame({'A':[True, False, np.nan], 'B':[True, False, True]})
    In[2]: df.dropna(inplace=True)
    In[3]: df['A']
    Out[3]:
    0    True
    1   False
    Name: A, dtype object
    In[4]: ~df['A']
    Out[4]:
    0   -2
    0   -1
    Name: A, dtype object

    Después de hablar con sus colegas acerca de esto tengo una explicación: parece que el panda es volver al operador bit a bit:

    In [1]: ~True
    Out[1]: -2
  3. 12

    Acabo de darle un tiro:

    In [9]: s = Series([True, True, True, False])
    
    In [10]: s
    Out[10]: 
    0     True
    1     True
    2     True
    3    False
    
    In [11]: -s
    Out[11]: 
    0    False
    1    False
    2    False
    3     True
    • Yo, literalmente, se trató de cada operador distinto de -! Voy a tener esto en cuenta para la próxima vez.
  4. 5

    También puede utilizar numpy.invertir:

    In [1]: import numpy as np
    
    In [2]: import pandas as pd
    
    In [3]: s = pd.Series([True, True, False, True])
    
    In [4]: np.invert(s)
    Out[4]: 
    0    False
    1    False
    2     True
    3    False

    EDIT: La diferencia en el rendimiento aparece en Ubuntu 12.04, Python 2.7, NumPy 1.7.0 – no parece existe con NumPy 1.6.2 aunque:

    In [5]: %timeit (-s)
    10000 loops, best of 3: 26.8 us per loop
    
    In [6]: %timeit np.invert(s)
    100000 loops, best of 3: 7.85 us per loop
    
    In [7]: %timeit ~s
    10000 loops, best of 3: 27.3 us per loop
    • Muy cool! Gracias por la referencia!
    • puede que no sea correcto en una plataforma diferente. Win 7, python 3.6.3 numpy 1.13.3, pandas 0.20.3, (-s) será el más rápido, (~s) es el segundo, y np.invert(s) es la opción más lenta

Dejar respuesta

Please enter your comment!
Please enter your name here