2017-03-03 5 views
0

Ich habe eine leere Zeile nach jeder Ebene 0 Zeile Label in der folgenden DataFrame für eine bequemere Anzeige platziert. Ich hatte eine Reihe von Werten in jedem, die ich nicht brauchte, also verwandelte ich das.Hinzufügen einer leeren Zeile zu einem hierarchischen indizierten Pandas-Datenrahmen

Was ist der richtige Weg, im Gegensatz zu meinem Hackjob?

       B      S 
         Depth3 Depth2 Depth1 Depth1 Depth2 Depth3 
Market1 actionIndicator  B  B  B  S  S  S 
     limit    555 557 558  560  561  562 
     quantity   18.474 8.355 8.286 0.626 17.101 17.576 
Market2 actionIndicator  B  B  B  S  S  S 
     limit    475 477 478  479  480  481 
     quantity   30.156 8.329 8.182 37.483 84.416 37.659 
Market3 actionIndicator  B  B  B  S  S  S 
     limit    583 586 587  589  590  591 
     quantity   39.548 8.382 8.18 55.181 17.289 17.689 

Ich wollte dies:

     B      S 
        Depth3 Depth2 Depth1 Depth1 Depth2 Depth3 
Market1 limit  555 557 558  560  561  562 
     quantity 18.474 8.355 8.286 0.626 17.101 17.576 

Market2 limit  475 477 478  479  480  481 
     quantity 30.156 8.329 8.182 37.483 84.416 37.659 

Market3 limit  583 586 587  589  590  591 
     quantity 39.548 8.382 8.18 55.181 17.289 17.689 

Die folgende auf dem ursprünglichen Datenrahmen verwendet wurde, um es zu erreichen:

df = df.reindex(display_order, level=0).reindex(["limit", "quantity", 
               "actionIndicator"], level=1) 
df.index = df.index.set_levels(["limit", "quantity", ""], level=1) 
for level in set(df.index.get_level_values(0)): 
    df.ix[(level, "")] = "" 

Voll Code:

data = { 
'Market1': {'B': {'Depth1': {'actionIndicator': 'B', 
    'limit': '558', 
    'quantity': '8.286'}, 
    'Depth2': {'actionIndicator': 'B', 'limit': '557', 'quantity': '8.355'}, 
    'Depth3': {'actionIndicator': 'B', 'limit': '555', 'quantity': '18.474'}}, 
    'S': {'Depth1': {'actionIndicator': 'S', 
    'limit': '560', 
    'quantity': '0.626'}, 
    'Depth2': {'actionIndicator': 'S', 'limit': '561', 'quantity': '17.101'}, 
    'Depth3': {'actionIndicator': 'S', 'limit': '562', 'quantity': '17.576'}}}, 
'Market2': {'B': {'Depth1': {'actionIndicator': 'B', 
    'limit': '478', 
    'quantity': '8.182'}, 
    'Depth2': {'actionIndicator': 'B', 'limit': '477', 'quantity': '8.329'}, 
    'Depth3': {'actionIndicator': 'B', 'limit': '475', 'quantity': '30.156'}}, 
    'S': {'Depth1': {'actionIndicator': 'S', 
    'limit': '479', 
    'quantity': '37.483'}, 
    'Depth2': {'actionIndicator': 'S', 'limit': '480', 'quantity': '84.416'}, 
    'Depth3': {'actionIndicator': 'S', 'limit': '481', 'quantity': '37.659'}}}, 
'Market3': {'B': {'Depth1': {'actionIndicator': 'B', 
    'limit': '587', 
    'quantity': '8.18'}, 
    'Depth2': {'actionIndicator': 'B', 'limit': '586', 'quantity': '8.382'}, 
    'Depth3': {'actionIndicator': 'B', 'limit': '583', 'quantity': '39.548'}}, 
    'S': {'Depth1': {'actionIndicator': 'S', 
    'limit': '589', 
    'quantity': '55.181'}, 
    'Depth2': {'actionIndicator': 'S', 'limit': '590', 'quantity': '17.289'}, 
    'Depth3': {'actionIndicator': 'S', 'limit': '591', 'quantity': '17.689'}}}, 
} 

df = DataFrame.from_dict(
     {(k1, k2, k3): data[k1][k2][k3] for k1 in data.keys() for k2 in 
     data[k1].keys() for k3 in data[k1][k2].keys()}, orient="columns") 

df = df.unstack().reorder_levels([0,3,2,1]).unstack(level=[3,2]) 
dfB = df[["B"]].sort_index(axis=1, ascending=False) 
dfS = df[["S"]] 
df = pd.concat([dfB, dfS], axis=1) 

df = df.reindex(["limit", "quantity", "actionIndicator"], level=1) 
df.index = df.index.set_levels(["limit", "quantity", ""], level=1) 
for level in set(df.index.get_level_values(0)): 
    df.ix[(level, "")] = "" 

print(df) 

Antwort

1

Sie verwenden können ein weiterer Hack:

df = pd.DataFrame.from_dict(
     {(k1, k2, k3): data[k1][k2][k3] for k1 in data.keys() for k2 in 
     data[k1].keys() for k3 in data[k1][k2].keys()}, orient="columns") 

df = df.stack(0).swaplevel(1,0).sort_index() 
print (df) 
          B      S     
         Depth1 Depth2 Depth3 Depth1 Depth2 Depth3 
Market1 actionIndicator  B  B  B  S  S  S 
     limit    558 557  555  560  561  562 
     quantity   8.286 8.355 18.474 0.626 17.101 17.576 
Market2 actionIndicator  B  B  B  S  S  S 
     limit    478 477  475  479  480  481 
     quantity   8.182 8.329 30.156 37.483 84.416 37.659 
Market3 actionIndicator  B  B  B  S  S  S 
     limit    587 586  583  589  590  591 
     quantity   8.18 8.382 39.548 55.181 17.289 17.689 
#rename index value 'actionIndicator' for last for sort e.g. zzz 
df = df.rename(index={'actionIndicator':'zzz'}) 
#sorting index, zzz row is last in each group 
df = df.sort_index() 
#get mask where zzz 
mask = df.index.get_level_values(1) == 'zzz' 
#replace rows where mask is True by empty spaces 
df.loc[mask] = '' 
#replace value zzz to empty space 
df = df.rename(index={'zzz':''}) 
print (df) 
         B      S     
       Depth1 Depth2 Depth3 Depth1 Depth2 Depth3 
Market1 limit  558 557  555  560  561  562 
     quantity 8.286 8.355 18.474 0.626 17.101 17.576 

Market2 limit  478 477  475  479  480  481 
     quantity 8.182 8.329 30.156 37.483 84.416 37.659 

Market3 limit  587 586  583  589  590  591 
     quantity 8.18 8.382 39.548 55.181 17.289 17.689 

Eine andere mögliche Lösung mit reindex von MultiIndex.from_product:

#dynamically remove 'actionIndicator' and add it to the end of list 
a = 'actionIndicator' 
lvls = [lvl for lvl in df.index.levels[1] if lvl != a] + [a] 
print (lvls) 
['limit', 'quantity', 'actionIndicator'] 

df = df.reindex(pd.MultiIndex.from_product([df.index.levels[0],lvls])) 
mask = df.index.get_level_values(1) == a 
df.loc[mask] = '' 
df = df.rename(index={a:''}) 
print (df) 
         B      S     
       Depth1 Depth2 Depth3 Depth1 Depth2 Depth3 
Market1 limit  558 557  555  560  561  562 
     quantity 8.286 8.355 18.474 0.626 17.101 17.576 

Market2 limit  478 477  475  479  480  481 
     quantity 8.182 8.329 30.156 37.483 84.416 37.659 

Market3 limit  587 586  583  589  590  591 
     quantity 8.18 8.382 39.548 55.181 17.289 17.689 
Verwandte Themen