Tengo una serie como esta después de hacer groupby ('nombre') y usar la función mean () en otra columna
name
383 3.000000
663 1.000000
726 1.000000
737 9.000000
833 8.166667
¿Alguien podría mostrarme cómo filtrar las filas con valores medios de 1.000000? Gracias y agradezco mucho su ayuda.
Respuestas:
In [5]: import pandas as pd test = { 383: 3.000000, 663: 1.000000, 726: 1.000000, 737: 9.000000, 833: 8.166667 } s = pd.Series(test) s = s[s != 1] s Out[0]: 383 3.000000 737 9.000000 833 8.166667 dtype: float64
fuente
s
y luego usarlas dos veces en la expresión). Sin embargo, solo funciona desde pandas 0.18.Desde la versión 0.18+ de pandas, el filtrado de una serie también se puede hacer de la siguiente manera
test = { 383: 3.000000, 663: 1.000000, 726: 1.000000, 737: 9.000000, 833: 8.166667 } pd.Series(test).where(lambda x : x!=1).dropna()
Pago: http://pandas.pydata.org/pandas-docs/version/0.18.1/whatsnew.html#method-chaininng-improvements
fuente
Como señaló DACW , hay mejoras de encadenamiento de métodos en pandas 0.18.1 que hacen muy bien lo que busca.
En lugar de usar
.where
, puede pasar su función al.loc
indexador o al indexador de la serie[]
y evitar la llamada a.dropna
:test = pd.Series({ 383: 3.000000, 663: 1.000000, 726: 1.000000, 737: 9.000000, 833: 8.166667 }) test.loc[lambda x : x!=1] test[lambda x: x!=1]
Se admite un comportamiento similar en las clases DataFrame y NDFrame.
fuente
Una forma rápida de hacer esto es reconstruir usando
numpy
para cortar las matrices subyacentes. Vea los tiempos a continuación.mask = s.values != 1 pd.Series(s.values[mask], s.index[mask]) 0 383 3.000000 737 9.000000 833 8.166667 dtype: float64
sincronización ingenua
fuente
Otra forma es convertir primero a un DataFrame y usar el método de consulta (suponiendo que tenga instalado numexpr):
import pandas as pd test = { 383: 3.000000, 663: 1.000000, 726: 1.000000, 737: 9.000000, 833: 8.166667 } s = pd.Series(test) s.to_frame(name='x').query("x != 1")
fuente
Si le gusta una operación encadenada, también puede usar la
compress
función:test = pd.Series({ 383: 3.000000, 663: 1.000000, 726: 1.000000, 737: 9.000000, 833: 8.166667 }) test.compress(lambda x: x != 1) # 383 3.000000 # 737 9.000000 # 833 8.166667 # dtype: float64
fuente
En mi caso tuve una serie panda donde los valores son tuplas de caracteres :
Out[67] 0 (H, H, H, H) 1 (H, H, H, T) 2 (H, H, T, H) 3 (H, H, T, T) 4 (H, T, H, H)
Por lo tanto, podría usar la indexación para filtrar la serie, pero para crear el índice que necesitaba
apply
. Mi condición es "encontrar todas las tuplas que tengan exactamente una 'H'".series_of_tuples[series_of_tuples.apply(lambda x: x.count('H')==1)]
Admito que no es "encadenable" (es decir, observe que repito
series_of_tuples
dos veces; debe almacenar cualquier serie temporal en una variable para que pueda llamar a aplicar (...) en ella).También puede haber otros métodos (además
.apply(...)
) que pueden operar por elementos para producir un índice booleano.Muchas otras respuestas (incluida la respuesta aceptada) usando las funciones encadenables como:
.compress()
.where()
.loc[]
[]
¡Estos aceptan callables (lambdas) que se aplican a la Serie , no a los valores individuales en esas series!
Por lo tanto, mi Serie de tuplas se comportó de manera extraña cuando intenté usar mi condición anterior / invocable / lambda, con cualquiera de las funciones encadenables, como
.loc[]
:series_of_tuples.loc[lambda x: x.count('H')==1]
Produce el error:
KeyError: 'El nivel H debe ser el mismo que el nombre (Ninguno)'
Estaba muy confundido, pero parece estar usando la función Series.count
series_of_tuples.count(...)
, que no es lo que quería.Admito que una estructura de datos alternativa puede ser mejor:
Esto crea una serie de cadenas (es decir, concatenando la tupla; uniendo los caracteres de la tupla en una sola cadena)
series_of_tuples.apply(''.join)
Entonces puedo usar el encadenable
Series.str.count
series_of_tuples.apply(''.join).str.count('H')==1
fuente