¿Cómo puedo obtener el elemento lógico NO de una Serie de pandas?
Tengo un objeto pandas Series
que contiene valores booleanos. ¿Cómo puedo obtener una serie que contiene el NOT
lógico de cada valor?
Por ejemplo, considere una serie que contenga:
True
True
True
False
La serie que me gustaría obtener contendría:
False
False
False
True
Esto parece que debería ser razonablemente simple, pero aparentemente he perdido mi mojo =(
4 answers
Para invertir una serie booleana, use ~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
Usando 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
A partir de Pandas 0.13.0, las Series ya no son subclases de numpy.ndarray
; ahora son subclases de pd.NDFrame
. Esto podría tener algo que ver con 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, incluidas las versiones de hardware, compilador, sistema operativo, Python, NumPy y Pandas.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-28 18:58:59
Solo le doy una oportunidad:
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-14 10:53:08
La respuesta de@unutbu es acertada, solo quería agregar una advertencia de que su máscara debe ser dtype bool, no 'object'. Es decir, su máscara no puede tener nunca tuvo ninguna nan. Vea aquí - incluso si su máscara está libre de nan ahora, seguirá siendo de tipo 'objeto'.
El inverso de una serie 'object' no arrojará un error, en su lugar obtendrá una máscara de basura de ints que no funcionará como 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 colegas sobre esto tengo una explicación: Parece como pandas está volviendo al operador bitwise:
In [1]: ~True
Out[1]: -2
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-08 17:29:20
También Se puede utilizar numpy.invert
:
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
EDITAR: La diferencia en el rendimiento aparece en Ubuntu 12.04, Python 2.7, NumPy 1.7.0-no parece existir usando 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-14 15:34:19