2016-12-18 1 views
1

Afer joignant deux trames de données:Python Pandas dataframe: lignes de groupe et réduire les groupes avec fonction personnalisée

left_dict = {                     
    'id1': [1,2,3,4,5],                   
    'val1': [10,20,30,40,50],                 
    'lft': ['a','b','c','d','e']                
}                        

right_dict = {                     
    'id1': [1,7,3,4,8,1,3],                  
    'val2': [100,700,300,400,800,110,330],              
    'rgt': [1.1,2.2,3.3,4.4,5.5,6.6,7.7]              
}                        

left = pd.DataFrame(left_dict)                 
right = pd.DataFrame(right_dict)                

r = pd.merge(left, right, how='outer', on='id1', indicator=False) 

je suis résultant trame de données:

id1 lft val1 rgt val2                 
0 1.0 a 10.0 1.1 100.0                 
1 1.0 a 10.0 6.6 110.0                 
2 2.0 b 20.0 NaN NaN                 
3 3.0 c 30.0 3.3 300.0                 
4 3.0 c 30.0 7.7 330.0                 
5 4.0 d 40.0 4.4 400.0                 
6 5.0 e 50.0 NaN NaN                 
7 7.0 NaN NaN 2.2 700.0                 
8 8.0 NaN NaN 5.5 800.0                 

Maintenant je dois plier les lignes avec le même 'id1', 'lft' et 'rgt' en une ligne avec 'id1', 'lft', 'rgt', inchangé et ajoute une nouvelle colonne 'xxx' à ce bloc de données. Les valeurs dans cette colonne « xxx » sont calculés avec une fonction

def f(val1, val2): 
    if math.isnan(val2): 
     r = val1 
    else: 
     if math.isnan(val1): 
      r = val2 
    else: 
     r = val1 * 2 + val2 * 3 
    return r 

donc trame de données résultant devrait être ceci:

id1 lft val1 rgt val2 xxx                
0 1.0 a 10.0 1.1 100.0 320.0                
1 2.0 b 20.0 NaN NaN 20.0                
2 3.0 c 30.0 3.3 300.0 960.0                
3 4.0 d 40.0 4.4 400.0 40.0                
4 5.0 e 50.0 NaN NaN 50.0                
5 7.0 NaN NaN 2.2 700.0 700.0                
6 8.0 NaN NaN 5.5 800.0 800.0                

Je tentais d'utiliser:

In [85]: r.groupby(['id1','val1', 'lft', 'rgt']).groups 

Ce retourne un dictionnaire avec des valeurs égales aux numéros de ligne dans les groupes, ce qui n'aide pas du tout. Des idées sur comment plier et réduire les lignes?

+2

Lors du "pliage" des lignes, comment choisissez-vous les valeurs de "rgt" et "val1" dans la structure de données finale si "id1" est identique pour plusieurs lignes? – Peaceful

+0

Vous avez raison, j'ai raté cette partie. Maintenant, j'ai corrigé mon problème avec " Maintenant, je dois replier les lignes avec les mêmes 'id1', 'lft' et 'rgt' en une ligne avec 'id1', 'lft', 'rgt', inchangé et ajouter un nouveau La colonne 'xxx' de ce bloc de données Les valeurs de cette colonne 'xxx' sont calculées avec la fonction " – zork

+0

" Que voulez-vous dire par "rangées"? – josh

Répondre

0
r['xxx'] = [f(x[1]['val1'],x[1]['val2']) for x in r.iterrows()] 

ne fonctionnera probablement, mais gardez à l'esprit que pour les combinaisons dupliquées, vous obtiendrez des lignes dupliquées, est que la logique que vous cherchez?