2013-06-20 6 views
3

J'ai un tableau entier de 1D de "facteurs" qui signifient des choses différentes. Parfois, plusieurs chiffres signifient la même chose:La version python de R% en% fonction

import numpy as np 

vec = np.arange(1, 10) 
comps = { 
    'good': (3,), 
    'bad': (4, 5, 9,), 
    'ok': (2, 3,) 
} 

result = {} 
for name in comps.keys(): 
    result[name] = np.zeros(len(vec), 'bool') 
    for i, v in enumerate(vec): 
     result[name][i] = v in comps[name] 

Ceci est la sortie désirée. Cependant lorsque vec devient grand et le nombre de clés dans comps augmente, cela devient assez lent. De plus, son dégueu ... En R il y a la fonction %in%:

vec = 1:10 
comp = list(
    good = 3, 
    bad = c(4:5, 9), 
    ok = 2:3 
) 

lapply(comp, function(x) vec %in% x) 

Ce qui fait la comparaison entre chaque valeur par éléments sur le côté gauche à chaque valeur dans le droit et renvoie le résultat « ou logique » comme vecteur booléen de la même longueur que vec.

Je peux me rapprocher et plus propre à l'aide pandas:

import pandas as pd 

DF = pd.DataFrame({'vec': vec}) 

result = {} 
for name in comps.keys(): 
    result[name] = DF.vec.apply(lambda x: x in comps[name]) 

similaires à this question... mais je veux le tableau plutôt qu'un élément par élément simple booléen que mon résultat.

Quelle est la meilleure façon de faire cela en python? (Numpy pandas?)

+0

est 3 intentionnellement bon et ok? –

+0

@AndyHayden C'est sûr! – Justin

Répondre

2

Vous pouvez créer ce dictionnaire à l'aide d'une compréhension (et la méthode Série isin):

pd.DataFrame({k: df.vec.isin(v) for k, v in comps.iteritems()}) 
+0

Je savais qu'il y avait quelque chose, je ne pouvais pas le trouver! FWIW la méthode 'isin' est environ 10 fois plus rapide que l'utilisation de' apply' sur mon jeu de données particulier. – Justin