Puis-je utiliser ma fonction d'aide pour déterminer si un plan était un trois points comme fonction de filtre dans Pandas? Ma fonction actuelle est beaucoup plus complexe, mais je l'ai simplifiée pour cette question.
def isThree(x, y):
return (x + y == 3)
print data[isThree(data['x'], data['y'])].head()
4 Réponses :
Dans ce cas, je recommanderais d'utiliser np.where () . Consultez l'exemple suivant:
x y 3 Pointer 0 1 0 0 1 2 1 1 2 4 2 0 3 2 0 0 4 3 0 1 5 1 2 1 6 2 4 0 7 3 0 1 8 4 1 0 9 0 2 0
Rendements:
import pandas as pd
import numpy as np
df = pd.DataFrame({'x': [1,2,4,2,3,1,2,3,4,0], 'y': [0,1,2,0,0,2,4,0,1,2]})
df['3 Pointer'] = np.where(df['x']+df['y']==3, 1, 0)
Cela ne devrait pas être la réponse car la question déclare "Ma fonction actuelle est beaucoup plus complexe, mais je l'ai simplifiée pour cette question." Donc, fondamentalement, il veut utiliser une autre fonction.
Cela répond précisément à la question posée et étant donné une fonction plus complexe, il n'y a toujours pas de raison concrète donnée par l'OP que np.where () ne suffirait pas.
d'accord avec @ rahlf23 je ne vois aucune raison pour laquelle cela ne serait pas valide
@KartikeyaSharma a raison. Y aurait-il un moyen d'inclure «isThree» dans un appel where?
@JSells oui, de la même manière que vous avez fait isThree (données ['x'], données ['y']) . L'indexation booléenne et np.where acceptent les tableaux booléens.
Vous pouvez utiliser np.vectorize. La documentation est ici https://docs.scipy.org/doc /numpy/reference/generated/numpy.vectorize.html
def isThree(x, y):
return (x + y == 3)
df=pd.DataFrame({'A':[1,2],'B':[2,0]})
df['new_column'] = np.vectorize(isThree)(df['A'], df['B'])
Cela ne vectorise rien (en termes de performances).
Merci! Cela a fonctionné, mais y a-t-il aussi un moyen de filtrer sans créer une nouvelle colonne? Sinon, cela fonctionne bien aussi.
@JSells n'utilise pas np.vectorize ici. Il n'y a pas besoin, les opérations sont déjà vectorisées , et cette fonction est essentiellement une boucle for de niveau python
@JSells Je ne vois pas de toute façon filtrer sans créer de colonne. Je suggérerais d'utiliser d'autres solutions si c'est votre objectif ultime. Je vous suggère également d'essayer ceci et de rechercher la performance et comment cela fonctionne pour vous!
Oui, tant que votre fonction renvoie une série booléenne avec le même index, vous pouvez découper votre DataFrame d'origine avec la sortie. Dans cet exemple simple, nous pouvons passer Series à votre fonction:
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randint(0, 4, (30, 2)))
def isThree(x, y):
return x + y == 3
df[isThree(df[0], df[1])]
# 0 1
#2 2 1
#5 2 1
#9 0 3
#11 2 1
#12 0 3
#13 2 1
#27 3 0
Oui:
x y 0 1 2 1 2 1 2 2 1 3 1 2 4 2 1
Sortie :
def isThree(x, y):
return (x + y == 3)
print(data[isThree(data['x'], data['y'])].head())
x y 0 1 2 1 2 1 2 2 1 3 1 2 4 2 1 5 2 1 6 2 1 7 2 1 8 2 1 9 2 2
Sortie:
import numpy as np
import pandas as pd
data = pd.DataFrame({'x': np.random.randint(1,3,10),
'y': np.random.randint(1,3,10)})
print(data)
Cela semble fonctionner avec mon code merci!
Heureux de l'entendre!
J'ai regardé cela, mais ma fonction réelle est assez grande et je veux pouvoir la réutiliser. Je ne pensais pas qu'un lambda fonctionnerait. Y a-t-il d'autres options applicables?
Utilisez numpy.vectorize qui est incroyablement rapide.
@JSells que vous n'avez jamais besoin d'utiliser un
lambda, en fait Guido voulait apparemment supprimer la construction en Python 3. Vous pouvez faire n'importe quoi avec une fonction créée avec une définition de fonction complète que vous pouvez avec unlambda, sauf bien sûr, rendre cette fonction anonyme (ce qui n'est jamais quelque chose qui doit se produire). Mettre en tout cas.applyn'est pas nécessaire ici. C'est généralement un dernier recours@KartikeyaSharma euh, non, ce n'est pas le cas.
numpy.vectorizeest une méthode pratique , il déclare même là dans la documentation "La fonction vectorize est fournie principalement pour la commodité, pas pour les performances. L'implémentation est essentiellement une boucle for."L'objectif ici est-il de sous-définir le DataFrame d'origine ou d'attribuer une nouvelle colonne en fonction de la valeur booléenne?
@ juanpa.arrivillaga Plus vos fonctions sont complexes, plus vous verrez que les performances ne seront pas si différentes car ici il est dit que la fonction est complexe.
@KartikeyaSharma Je ne vois pas cela, et en tout cas, il existe de meilleures solutions, comme utiliser
pd.DataFrame.query, si vous êtes inquiet du trop grand nombre de tableaux intermédiaires@ALollz j'essaye de filtrer certaines lignes