2016-07-30 23 views
1

Ich habe eine Multiindex Serie (3 Indizes), die wie folgt aussieht:Verwenden Pandas Datenrahmen Verzögerung Funktion von MultiIindex Serie hinzufügen

Week ID_1 ID_2 
3  26  1182   39.0 
       4767   42.0 
       31393   20.0 
       31690   42.0 
       32962   3.0 
.................................... 

Ich habe auch einen Datenrahmen df, die alle Spalten (und mehr) enthält verwendet Für Indizes in der Reihe oben, und ich möchte eine neue Spalte in meinem Datenrahmen df erstellen, die den Wert ID_1 und ID_2 und Week - 2 aus der Serie enthält.

Zum Beispiel für die Zeile in Datenrahmen, die ID_1 = 26, ID_2 = 1182 und Week = 3 hat, möchte ich in der Serie von ID_1 = 26, ID_2 = 1182 und Week = 1 (3-2) und legte es auf dieser Zeile in einem neuen indiziert den Wert anzupassen Säule. Ferner könnte meine Serie nicht unbedingt den Wert durch den Datenrahmen erforderlich ist, in dem Fall, dass ich gerade jetzt rechts

0 haben möchte, ich dies durch den Einsatz zu tun versuche:

[multiindex_series.get((x[1].get('week', 2) - 2, x[1].get('ID_1', 0), x[1].get('ID_2', 0))) for x in df.iterrows()] 

Dies ist jedoch sehr langsam und Speicher hungrig und ich fragte mich, was sind bessere Möglichkeiten, dies zu tun.

FWIW wurde die Serie

saved_groupby = df.groupby(['Week', 'ID_1', 'ID_2'])['Target'].median() 

mit geschaffen und ich bin bereit, es eine andere Art und Weise zu tun, wenn eine bessere Pfade existieren zu schaffen, was ich suche.

Antwort

3

Erhöhen Sie die Week von 2:

saved_groupby = df.groupby(['Week', 'ID_1', 'ID_2'])['Target'].median() 
saved_groupby = saved_groupby.reset_index() 
saved_groupby['Week'] = saved_groupby['Week'] + 2 

und dann verschmelzen df mit saved_groupby:

result = pd.merge(df, saved_groupby, on=['Week', 'ID_1', 'ID_2'], how='left') 

Diese df mit dem Ziel Median von 2 Wochen verstärken wird. Um den Median (Ziel) saved_groupby Spalte 0, wenn es keine Übereinstimmung gibt, fillna verwendet NaNs auf 0 zu ändern:

result['Median'] = result['Median'].fillna(0) 

Zum Beispiel

import numpy as np 
import pandas as pd 
np.random.seed(2016) 

df = pd.DataFrame(np.random.randint(5, size=(20,5)), 
        columns=['Week', 'ID_1', 'ID_2', 'Target', 'Foo']) 

saved_groupby = df.groupby(['Week', 'ID_1', 'ID_2'])['Target'].median() 
saved_groupby = saved_groupby.reset_index() 
saved_groupby['Week'] = saved_groupby['Week'] + 2 
saved_groupby = saved_groupby.rename(columns={'Target':'Median'}) 

result = pd.merge(df, saved_groupby, on=['Week', 'ID_1', 'ID_2'], how='left') 
result['Median'] = result['Median'].fillna(0) 
print(result) 

Ausbeuten

Week ID_1 ID_2 Target Foo Median 
0  3  2  3  4 2  0.0 
1  3  3  0  3 4  0.0 
2  4  3  0  1 2  0.0 
3  3  4  1  1 1  0.0 
4  2  4  2  0 3  2.0 
5  1  0  1  4 4  0.0 
6  2  3  4  0 0  0.0 
7  4  0  0  2 3  0.0 
8  3  4  3  2 2  0.0 
9  2  2  4  0 1  0.0 
10  2  0  4  4 2  0.0 
11  1  1  3  0 0  0.0 
12  0  1  0  2 0  0.0 
13  4  0  4  0 3  4.0 
14  1  2  1  3 1  0.0 
15  3  0  1  3 4  2.0 
16  0  4  2  2 4  0.0 
17  1  1  4  4 2  0.0 
18  4  1  0  3 0  0.0 
19  1  0  1  0 0  0.0 
+0

Brilliant, habe nicht einmal in Betracht gezogen, den Index zurückzusetzen, danke! Ich denke, dass, um meinem Problem zu entsprechen, ich ** 2 ** in die Woche hinzufügen sollte, nein? Ansonsten wird der Datenrahmen das Medianziel zukünftiger Wochen enthalten, glaube ich. – confused00

+0

Rechts, wenn Sie den ursprünglichen Datenrahmen mit dem Medianziel von vor 2 Wochen erweitern möchten, verwenden Sie 'saved_groupby ['Week'] = saved_groupby ['Week'] + 2'. – unutbu