2016-11-26 3 views
1

Je voudrais créer une colonne appelée str_bos dans un DataFrame existant appelé result. J'ai les colonnes suivantes - 'str_nbr', 'ZIP Sales', 'str_Sales', 'ZIP_Distinct #', 'ZIP_Share_of_Str_Sales', 'Counter', 'Str_BOS_Cum%', 'Str_Sales_Rank'.Ajouter un champ calculé dans un DataFrame

Voici ce que j'ai trouvé. Mais, il faut 2 heures pour terminer. Cependant, d'autres opérations (comme le tri, la fusion, etc.) prennent quelques secondes. Qu'est-ce qui me manque ici?

def str_bos(row): 
    if row['str_sales_rank'] == 1 or row['str_bos_cum%'] <= 0.1: 
     return 1 
    elif row['str_bos_cum%'] <= 0.2: 
     return 2 
    elif row['str_bos_cum%'] <= 0.3: 
     return 3 
    elif row['str_bos_cum%'] <= 0.4: 
     return 4 
    elif row['str_bos_cum%'] <= 0.5: 
     return 5 
    elif row['str_bos_cum%'] <= 0.6: 
     return 6 
    elif row['str_bos_cum%'] <= 0.7: 
     return 7 
    elif row['str_bos_cum%'] <= 0.8: 
     return 8 
    elif row['str_bos_cum%'] <= 0.9: 
     return 9 
    else: 
     return 10 

result['str_bos'] = result.apply(lambda row: str_bos(row), axis=1) 
+1

La raison pour laquelle votre code est lent est que la méthode '.apply' itère sur chaque ligne, alors que les méthodes vectorisés faire des calculs sur toute la colonne immediatement. Dans les pandas, vous devez éviter d'itéter sur les rangs - il est presque garanti d'avoir des performances terribles. Ce blog a une bonne explication (section Itération, Appliquer, et vectorisation): https://tomaugspurger.github.io/modern-4-performance.html – DataSwede

Répondre

1

J'utiliser la méthode cut() ici:

In [21]: df = pd.DataFrame(np.random.rand(10), columns=['A']) 

In [22]: df 
Out[22]: 
      A 
0 0.513425 
1 0.973631 
2 0.549615 
3 0.747600 
4 0.099415 
5 0.737613 
6 0.885567 
7 0.720187 
8 0.446683 
9 0.434688 

In [23]: df['str_bos'] = pd.cut(df.A, bins=np.arange(0, 1.1, 0.1), labels=np.arange(10)+1) 

In [24]: df 
Out[24]: 
      A str_bos 
0 0.513425  6 
1 0.973631  10 
2 0.549615  6 
3 0.747600  8 
4 0.099415  1 
5 0.737613  8 
6 0.885567  9 
7 0.720187  8 
8 0.446683  5 
9 0.434688  5