2017-01-16 3 views
2

Ich vergleiche eine Reihe von acht Algorithmen (solver Spalte) mit einer Reihe von Instanzen, jede Instanz wird einmal für jeden Algorithmus und eine Ebene eines Parameters D ausgeführt (geht von 1 bis 10). So würde die resultierende Datenrahmen wie folgt aussehen:Rang in Gruppen mit Python-Pandas

  instance D z    solver 
0 1000_ep0.0075 1 994   threatened 
1 1000_ep0.0075 1 993    desc 
2 1000_ep0.0075 1 994    degree 
3 1000_ep0.0075 1 993 threatened_desc 
4 1000_ep0.0075 1 993 threatened_degree 
5 1000_ep0.0075 1 994   desc_later 
6 1000_ep0.0075 1 994  degree_later 
7 1000_ep0.0075 1 993   dyn_degree 
8 1000_ep0.0075 2 986   threatened 
9 1000_ep0.0075 2 987    desc 
10 1000_ep0.0075 2 988    degree 
11 1000_ep0.0075 2 987 threatened_desc 
12 1000_ep0.0075 2 986 threatened_degree 
13 1000_ep0.0075 2 987   desc_later 
14 1000_ep0.0075 2 988  degree_later 
15 1000_ep0.0075 2 987   dyn_degree 
.... 

Wo die z Spalte auf den Wert durch den Algorithmus (kleiner, desto besser) gefunden entspricht.

Ich möchte dem Datenrahmen eine Spalte hinzufügen, die dem Rang jedes Algorithmus gemäß dem Wert z für jede Kombination <instance, D> entspricht. Für das obige Beispiel, so etwas wie dies würde:

  instance D z    solver z_rank 
0 1000_ep0.0075 1 994   threatened 2 
1 1000_ep0.0075 1 993    desc 1 
2 1000_ep0.0075 1 994    degree 2 
3 1000_ep0.0075 1 993 threatened_desc 1 
4 1000_ep0.0075 1 993 threatened_degree 1 
5 1000_ep0.0075 1 994   desc_later 2 
6 1000_ep0.0075 1 994  degree_later 2 
7 1000_ep0.0075 1 993   dyn_degree 1 
8 1000_ep0.0075 2 986   threatened 1 
9 1000_ep0.0075 2 987    desc 2 
10 1000_ep0.0075 2 988    degree 3 
11 1000_ep0.0075 2 987 threatened_desc 2 
12 1000_ep0.0075 2 986 threatened_degree 1 
13 1000_ep0.0075 2 987   desc_later 2 
14 1000_ep0.0075 2 988  degree_later 3 
15 1000_ep0.0075 2 987   dyn_degree 2 
... 

Mit python-pandas, ist es das, was ich bisher bekommen kann:

df.loc[:, 'z_rank'] = df_rg.groupby(['instance', 'D'])['z'].rank() 
df.head(16) 
     instance D z    solver z_rank 
0 1000_ep0.0075 1 994   threatened 47.5 
1 1000_ep0.0075 1 993    desc 16.5 
2 1000_ep0.0075 1 994    degree 47.5 
3 1000_ep0.0075 1 993 threatened_desc 16.5 
4 1000_ep0.0075 1 993 threatened_degree 16.5 
5 1000_ep0.0075 1 994   desc_later 47.5 
6 1000_ep0.0075 1 994  degree_later 47.5 
7 1000_ep0.0075 1 993   dyn_degree 16.5 
8 1000_ep0.0075 2 986   threatened  7.0 
9 1000_ep0.0075 2 987    desc 18.5 
10 1000_ep0.0075 2 988    degree 44.5 
11 1000_ep0.0075 2 987 threatened_desc 18.5 
12 1000_ep0.0075 2 986 threatened_degree  7.0 
13 1000_ep0.0075 2 987   desc_later 18.5 
14 1000_ep0.0075 2 988  degree_later 44.5 
15 1000_ep0.0075 2 987   dyn_degree 18.5 

die eindeutig nicht ist, was ich will.

Könnte mir jemand dabei helfen?

Antwort

5

Sie benötigen method=dense in SeriesGroupBy.rank() wo die Reihen um 1 zwischen den Gruppen zu erhöhen:

df['z_rank'] = df.groupby(['instance', 'D'])['z'].rank(method='dense').astype(int) 

enter image description here

+0

Nizza! Vielen Dank! Gibt es eine Möglichkeit, den Rang zwischen den Gruppen nicht zu erhöhen? –

+0

Also, wie wäre die Ausgabe in einem solchen Fall? –

+0

Da, wenn ich die dichte Methode in der gesamten df anwenden, bekomme ich Folgendes: http://pastebin.com/raw/9me5tnTa. In der ersten Gruppe ist der kleinste Rang 3, wobei 1 sein sollte. Ich nehme an, dass der Anstieg zwischen den Gruppen –

0

ich es mit dem folgenden Code versucht. Ich bekomme 1 für alle auf der FrSeg-Spalte.

Merge_Data['FrSeg'] = Merge_Data.groupby(['CustomerKey']) 
['Frequency'].rank(method='dense').astype(int) 

Ich frage mich, wie man es in 3 Gruppen bekommt. Ich habe Ziffern von 1 bis 68 in der Frequenz Spalte