python - sumar - funciones de pandas para leer datos a tablas
¿Cómo puedo obtener el elemento lógico NO a elementos de una serie de pandas? (4)
Tengo una pregunta relativamente directa, hoy. Tengo un objeto Series
panda 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 quisiera obtener contendría:
False
False
False
True
Parece que debería ser razonablemente simple, pero aparentemente he perdido mi mojo hoy = (
¡Gracias!
La respuesta de @ unutbu es perfecta, solo quería agregar una advertencia de que tu máscara debe ser dtype bool, no ''objeto''. Es decir, su máscara no puede haber tenido nunca ningún nan. Vea here : incluso si su máscara no está libre ahora, seguirá siendo del tipo ''objeto''.
La inversa de una serie de ''objetos'' no arrojará un error, en su lugar obtendrá una máscara de basura de entradas que no funcionará como esperaba.
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 que los pandas están volviendo al operador bit a bit:
In [1]: ~True
Out[1]: -2
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: los resultados del tiempo pueden variar dependiendo de muchos factores, incluidos el hardware, el compilador, el sistema operativo, las versiones de Python, NumPy y Pandas.
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
También puedes usar 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 - aunque no parece existir con NumPy 1.6.2:
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