2012-06-13 14 views
5

Ich habe vor kurzem über pandas gelernt und war glücklich, seine Analytics-Funktionalität zu sehen. Ich versuche, Excel-Array-Funktionen in die entsprechenden Pandas umzuwandeln, um Tabellenkalkulationen zu automatisieren, die ich für die Erstellung von Leistungsattributionsberichten erstellt habe. In diesem Beispiel habe ich eine neue Spalte in Excel basierend auf Bedingungen in anderen Spalten:Erstellen Sie Excel-ähnliche SUMME in Pandas

={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)} 

die Formel die Werte in dem „F“ array Aufsummieren wird (Sicherheitsgewichte), basierend auf bestimmte Bedingungen. "A" Array (Portfolio ID) ist eine bestimmte Anzahl, "B" Array (Sicherheits-ID) ist Null, "C" Array (Gruppenbeschreibung) ist "", "D" Array (Startdatum) ist das Datum der Zeile dass ich eingeschaltet bin, und "E" -Array (Enddatum) ist das Datum der Zeile, in der ich bin.

In Pandas verwende ich den DataFrame. Das Erstellen einer neuen Spalte auf einem Datenrahmen mit den ersten drei Bedingungen ist einfach, aber ich habe Schwierigkeiten mit den letzten beiden Bedingungen.

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() 

Offensichtlich ist die .ix [:] in den letzten beiden Bedingungen nicht für mich etwas zu tun, aber ist es eine Möglichkeit, die Summe der Bedingung der Reihe zu machen, die ich auf bin ohne Looping? Mein Ziel ist es, keine Schleifen zu machen, sondern reine Vektoroperationen zu verwenden.

Antwort

1

Ich bin sicher, dass es einen besseren Weg, aber das tat es in einer Schleife:

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

Sie möchten die Funktion anwenden verwenden und eine Lambda:

>> 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 

Lasst uns sagen, dass ich wollen Spalte C mal E Summe aber nur, wenn die Spalte B == 1 und D ist größer als 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() 

Es könnte sauberer sein, diese int aufzuspalten o zwei Schritten:

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

oder einfach für Geschwindigkeit Multiplikation zu verwenden:

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

Sie haben völlig Recht, dieses Problem ohne Schleifen wollen.

Verwandte Themen