J'ai une série comme celle-ci après avoir fait groupby ('name') et utilisé la fonction mean () sur une autre colonne
name
383 3.000000
663 1.000000
726 1.000000
737 9.000000
833 8.166667
Quelqu'un pourrait-il s'il vous plaît me montrer comment filtrer les lignes avec des valeurs moyennes de 1,000000? Merci et j'apprécie grandement votre aide.
Réponses:
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
la source
s
puis de l'utiliser deux fois dans l'expression). Cela ne fonctionne qu'à partir de pandas 0.18.À partir de la version 0.18+ de pandas, le filtrage d'une série peut également être effectué comme ci-dessous
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()
Paiement: http://pandas.pydata.org/pandas-docs/version/0.18.1/whatsnew.html#method-chaininng-improvements
la source
Comme l'a souligné DACW , il y a des améliorations de l'enchaînement des méthodes dans pandas 0.18.1 qui font très bien ce que vous recherchez.
Plutôt que d'utiliser
.where
, vous pouvez transmettre votre fonction à l'.loc
indexeur ou à l'indexeur de séries[]
et éviter l'appel à.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]
Un comportement similaire est pris en charge sur les classes DataFrame et NDFrame.
la source
Un moyen rapide de procéder consiste à reconstruire en utilisant
numpy
pour découper les tableaux sous-jacents. Voir les horaires ci-dessous.mask = s.values != 1 pd.Series(s.values[mask], s.index[mask]) 0 383 3.000000 737 9.000000 833 8.166667 dtype: float64
timing naïf
la source
Une autre méthode consiste à d'abord convertir en DataFrame et à utiliser la méthode de requête (en supposant que numexpr est installé):
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")
la source
Si vous aimez une opération chaînée, vous pouvez également utiliser la
compress
fonction: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
la source
Dans mon cas, j'avais une série de panda où les valeurs sont des tuples de caractères :
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)
Par conséquent, je pourrais utiliser l'indexation pour filtrer les séries, mais pour créer l'index dont j'avais besoin
apply
. Ma condition est "trouver tous les tuples qui ont exactement un" H "".series_of_tuples[series_of_tuples.apply(lambda x: x.count('H')==1)]
J'avoue que ce n'est pas "chaînable" , (c'est-à-dire que je le répète
series_of_tuples
deux fois; vous devez stocker toute série temporaire dans une variable pour pouvoir appeler apply (...) dessus).Il peut également y avoir d' autres méthodes (en plus
.apply(...)
) qui peuvent fonctionner élément par élément pour produire un index booléen.Beaucoup d'autres réponses (y compris la réponse acceptée) utilisant les fonctions chaînables comme:
.compress()
.where()
.loc[]
[]
Ceux-ci acceptent les callables (lambdas) qui sont appliqués à la série , pas aux valeurs individuelles de ces séries!
Par conséquent, ma série de tuples s'est comportée étrangement lorsque j'ai essayé d'utiliser ma condition ci-dessus / callable / lambda, avec l'une des fonctions chaînables, comme
.loc[]
:series_of_tuples.loc[lambda x: x.count('H')==1]
Produit l'erreur:
KeyError: 'Le niveau H doit être identique au nom (aucun)'
J'étais très confus, mais il semble utiliser la fonction Series.count
series_of_tuples.count(...)
, ce qui n'est pas ce que je voulais.J'admets qu'une structure de données alternative peut être meilleure:
Cela crée une série de chaînes (c'est-à-dire en concaténant le tuple; en joignant les caractères du tuple sur une seule chaîne)
series_of_tuples.apply(''.join)
Je peux donc utiliser le chaînable
Series.str.count
series_of_tuples.apply(''.join).str.count('H')==1
la source