5

Ich habe eine CSV, die so aussieht (und wenn in einen Pandas Dataframe mit gebracht wird, sieht es genauso aus).Mit den Werten einer vorherigen "Zeile" in einer Pandas-Serie

enter image description here

Ich mag die Werte in Spalte ad_requests nach folgenden Logik aktualisieren:

für eine bestimmte Zeile, wenn ad_requests einen Wert hat, es in Ruhe lassen. Geben Sie andernfalls einen Wert von den Wert der vorherigen Zeile für ad_requests abzüglich der vorherigen Zeile Wert für Eindrücke. So im ersten Beispiel möchten wir mit am Ende:

enter image description here

ich teilweise dort:

df["ad_requests"] = [i if not pd.isnull(i) else ??? for i in df["ad_requests"]] 

Und das ist, wo ich stecken. Nach der else möchte ich "zurückgehen" und auf die vorherige "Zeile" zugreifen, obwohl ich weiß, dass dies nicht so ist, wie Pandas verwendet werden sollen. Eine andere Sache zu beachten ist, dass die Zeilen immer in drei, nach Spalte ad_tag_name gruppiert werden. Wenn ich pd.groupby["ad_tag_name"] bin, kann ich das dann in eine list umwandeln und anfangen zu schneiden und indexieren, aber wieder denke ich, dass es einen besseren Weg geben muss, dies in Pandas zu tun (da es viele Dinge gibt).

Python: 2.7.10

Pandas:

pd.options.mode.chained_assignment = None #suppresses "SettingWithCopyWarning" 
for index, elem in enumerate(df['ad_requests']): 
    if pd.isnull(elem): 
     df['ad_requests'][index]=df['ad_requests'][index-1]-df['impressions'][index-1] 

Die Warnung kommt von der Tatsache, dass wir verändern: 0.18.0

+1

Hinweis: 'df.ad_requests.ffill() - df.impressions.cumsum(). Shift()' bringt Sie dorthin. –

+0

Interessant. Bei diesem Ansatz sind die Werte für die ersten leeren Zeilen * leicht * aus, dann werden sie jedoch negativ: http://imgur.com/a/k7faf – Pyderman

+0

Deshalb ist es ein Hinweis und keine vollständige Lösung. Der Cumsum muss jedes Mal auf 0 zurückgesetzt werden, wenn ad_requests ungleich Null ist, oder so ähnlich. –

Antwort

3

Sie werden so etwas wie dies tun wollen die Werte einer Ansicht eines Datenrahmens, die sich auf den ursprünglichen Datenrahmen auswirkt. Das wollen wir aber tun, darum geht es uns nicht wirklich an.

(Python 2.7.12 und Pandas 0.19.0)

EDIT:

die letzte Zeile des Codes von

Ändern
df['ad_requests'][index]=df['ad_requests'][index-1]-df['impressions'][index-1] 

zu

df.at[index,'ad_requests']=df.at[index-1,'ad_requests']-df.at[index-1,'impressions'] 

Beseitigt die Notwendigkeit, alle Warnungen zu unterdrücken:

for index, elem in enumerate(df['ad_requests']): 
    if pd.isnull(elem): 
     df.at[index,'ad_requests']=df.at[index-1,'ad_requests']-df.at[index-1,'impressions'] 
+1

Ich wusste, dass ich die Indizes der vorherigen Elemente irgendwie verwenden musste, aber "enumerate()" vergessen hatte. Und ich wusste, dass die endgültige Lösung kurz und ordentlich sein würde, wie die meisten Pandas-basierten Lösungen sind. Danke für diesen eleganten Ansatz. – Pyderman

Verwandte Themen