2012-06-13 6 views
5

Recentemente ho appreso su pandas ed ero felice di vedere la sua funzionalità di analisi. Sto cercando di convertire le funzioni dell'array di Excel nell'equivalente di Panda per automatizzare i fogli di calcolo che ho creato per la creazione di report di attribuzione delle prestazioni. In questo esempio, ho creato una nuova colonna in Excel basato su condizioni all'interno altre colonne:Creare SOMMAZIONI di tipo Excel in panda

={SUMIFS($F$10:$F$4518,$A$10:$A$4518,$C$4,$B$10:$B$4518,0,$C$10:$C$4518," ",$D$10:$D$4518,$D10,$E$10:$E$4518,$E10)} 

La formula è sommando i valori nella matrice "F" (pesi sicurezza) in base a determinate condizioni. L'array "A" (portfolio ID) è un certo numero, l'array "B" (id di sicurezza) è zero, l'array "C" (descrizione del gruppo) è "", l'array "D" (data di inizio) è la data della riga che sono attivo, e la matrice "E" (data di fine) è la data della riga in cui mi trovo.

In Pandas, sto utilizzando DataFrame. Creare una nuova colonna su un dataframe con le prime tre condizioni è semplice, ma sto avendo difficoltà con le ultime due condizioni.

reportAggregateDF['PORT_WEIGHT'] = reportAggregateDF['SEC_WEIGHT_RATE'] 
      [(reportAggregateDF['PORT_ID'] == portID) & 
      (reportAggregateDF['SEC_ID'] == 0) & 
      (reportAggregateDF['GROUP_LIST'] == " ") & 
      (reportAggregateDF['START_DATE'] == reportAggregateDF['START_DATE'].ix[:]) & 
      (reportAggregateDF['END_DATE'] == reportAggregateDF['END_DATE'].ix[:])].sum() 

Ovviamente il .ix [:] negli ultimi due condizioni non sta facendo nulla per me, ma c'è un modo per rendere la somma condizionale sulla riga che io sono senza di loop? Il mio obiettivo è non fare loop, ma usare le operazioni puramente vettoriali.

risposta

1

Sono sicuro che ci sia un modo migliore, ma questo fatto in un ciclo:

for idx, eachRecord in reportAggregateDF.T.iteritems(): 
reportAggregateDF['PORT_WEIGHT'].ix[idx] = reportAggregateDF['SEC_WEIGHT_RATE'][(reportAggregateDF['PORT_ID'] == portID) &    
    (reportAggregateDF['SEC_ID'] == 0) &    
    (reportAggregateDF['GROUP_LIST'] == " ") &    
    (reportAggregateDF['START_DATE'] == reportAggregateDF['START_DATE'].ix[idx]) &    
    (reportAggregateDF['END_DATE'] == reportAggregateDF['END_DATE'].ix[idx])].sum() 
6

Si desidera utilizzare la funzione e una lambda applicare:

>> df 
    A B C D  E 
0 mitfx 0 200 300 0.25 
1  gs 1 150 320 0.35 
2 duk 1 5 2 0.45 
3 bmo 1 145 65 0.65 

Diciamo che desidera sommare colonna C i tempi e, ma solo se la colonna B == 1 e D è superiore a 5:

df['matches'] = df.apply(lambda x: x['C'] * x['E'] if x['B'] == 1 and x['D'] > 5 else 0, axis=1) 
df.matches.sum() 

potrebbe essere più pulito per dividere questo int o due passaggi:

df_subset = df[(df.B == 1) & (df.D > 5)] 
df_subset.apply(lambda x: x.C * x.E, axis=1).sum() 

o da utilizzare semplicemente di moltiplicazione per la velocità:

df_subset = df[(df.B == 1) & (df.D > 5)] 
print sum(df_subset.C * df_subset.E) 

Lei ha assolutamente ragione a voler fare questo problema senza loop.