2017-02-15 1 views
1

J'ai un dataframe comme ça, avec des rangées de 10M:comment ajouter une nouvelle colonne catégorique pandas géants

     probe 
time      
2016-01-01 00:05:00 3 
2016-01-01 00:05:00 1 
2016-01-01 00:05:00 5 
2016-01-01 00:05:00 5 
2016-01-01 00:05:00 4 
2016-01-01 00:05:00 2 
2016-01-01 00:05:00 5 
2016-01-01 00:05:00 6 
2016-01-01 00:05:00 3 
2016-01-01 00:05:00 4 
2016-01-01 00:05:00 5 
2016-01-01 00:05:00 2 
2016-01-01 00:05:00 3 
2016-01-01 00:05:00 3 
2016-01-01 00:05:00 5 
Name: probe, dtype: uint8 

Je veux ajouter une colonne de categoricat en fonction de la valeur de probe

def categorize_R(x): 
    return "inner" if x['probe'] in (1, 4) else "outer" 

data['category_R'] = pandas.Categorical(data.apply(categorize_R, axis=1)) 

cette est terriblement lent. En fait, un calcul masque comme celui-ci:

mask_inner = (x['probe'] == 1) | (x['probe'] == 4) 

est assez rapide, mais je ne sais pas comment ajouter une colonne de type catégorique.

Répondre

1

Je pense que vous avez besoin numpy.where avec un masque créé par between:

mask = data.probe.between(1,4) 
data['category_R'] = pd.Categorical(np.where(mask, 'inner', 'outer')) 
print (data) 
        probe category_R 
time         
2016-01-01 00:05:00  3  inner 
2016-01-01 00:05:00  1  inner 
2016-01-01 00:05:00  5  outer 
2016-01-01 00:05:00  5  outer 
2016-01-01 00:05:00  4  inner 
2016-01-01 00:05:00  2  inner 
2016-01-01 00:05:00  5  outer 
2016-01-01 00:05:00  6  outer 
2016-01-01 00:05:00  3  inner 
2016-01-01 00:05:00  4  inner 
2016-01-01 00:05:00  5  outer 
2016-01-01 00:05:00  2  inner 
2016-01-01 00:05:00  3  inner 
2016-01-01 00:05:00  3  inner 
2016-01-01 00:05:00  5  outer 

Une autre solution est d'utiliser Categorical.from_codes, vérifiez également object creation-In [28]::

mask = (data['probe']==1) | (data['probe']==3) | (data['probe']==4) 

mask = (data['probe']==1) | (data['probe']==3) | (data['probe']==4) 
data['category_R'] = pd.Categorical(np.where(mask, 'inner', 'outer')) 
data['category_R1'] = pd.Categorical.from_codes(mask, ['outer','inner']) 
print (data) 
        probe category_R category_R1 
time            
2016-01-01 00:05:00  3  inner  inner 
2016-01-01 00:05:00  1  inner  inner 
2016-01-01 00:05:00  5  outer  outer 
2016-01-01 00:05:00  5  outer  outer 
2016-01-01 00:05:00  4  inner  inner 
2016-01-01 00:05:00  2  outer  outer 
2016-01-01 00:05:00  5  outer  outer 
2016-01-01 00:05:00  6  outer  outer 
2016-01-01 00:05:00  3  inner  inner 
2016-01-01 00:05:00  4  inner  inner 
2016-01-01 00:05:00  5  outer  outer 
2016-01-01 00:05:00  2  outer  outer 
2016-01-01 00:05:00  3  inner  inner 
2016-01-01 00:05:00  3  inner  inner 
2016-01-01 00:05:00  5  outer  outer 

minutage:

In [181]: %timeit pd.Categorical(np.where(mask, 'inner', 'outer')) 
1000 loops, best of 3: 196 µs per loop 

In [182]: %timeit pd.Categorical.from_codes(mask, ['outer','inner']) 
10000 loops, best of 3: 139 µs per loop 
+0

nous sommes proches. Le fait est que j'ai besoin de faire quelque chose de plus compliqué comme '(x [probe] == 1) | (x [sonde] == 3) | (x [probe] == 4) ' –

+0

en plus: il serait bon d'éviter la création de la série intermédiaire avec des chaînes et de créer directement celle avec les catégories –

+0

' numpy.where' est très rapide et la sortie est un tableau numpy , vous pouvez également changer le masque que vous avez besoin - vérifiez la dernière édition. – jezrael