2017-11-15 5 views
2

KontextConvert Pandas concat von Datenrahmen zu Multiindex

So durch ein Bündel von Dateien iterieren ich, wo jede Datei ein Thema ist, und in jeder Datei gibt es drei Spalten, die jeweils die x, y, Z-Achse an einem bestimmten Punkt (die Längen über Dateien sind nicht die gleichen). Ich möchte alle von ihnen in eine Multi-Index PD df setzen.

Was ich versucht habe

Ich fand this post und wenn ich es tun, scheint es zu funktionieren

d_ = dict() 
DATA_ROOT = "../sample_data/chest_mounted/" 
cutoff_min = 0 
for fileName in os.listdir(DATA_ROOT): 
    if ".csv" in fileName and '.swp' not in fileName: 
     with open(DATA_ROOT + fileName) as f: 
      data = np.asarray(list(map(lambda x: x.strip().split(",")[1:-1], f.readlines())), dtype=np.int) 
      subj_key = "Subject_" + str(fileName.split(".")[0]) 
      d_[subj_key] = pd.DataFrame(data, columns=['x_acc', 'y_acc', 'z_acc']) 
df = pd.concat(d_.values(), keys=d_.keys()) 

Wenn ich df.head tun() es sieht genauso aus wie das, was ich will (ich glaube?)

   x_acc y_acc z_acc 
Subject_1 0 1502 2215 2153 
      1 1667 2072 2047 
      2 1611 1957 1906 
      3 1601 1939 1831 
      4 1643 1965 1879 

Das Problem

Wenn ich jedoch versuche, nach Subject_x zu indizieren, erhalte ich einen Fehler. Stattdessen muss ich zuerst, wie etwas tun

df["x_acc"]["Subject_1"] 

, wo ich die x_acc Zugriff zuerst, dann die Subject_1.

Fragen

1) hatte ich den Eindruck, dass ich ein Multi-Index zu schaffen, sondern versuchen, df["x_acc"]["Subject_1"] das nicht der Fall zu sein scheint. Wie verwandle ich es dazu?

2) Gibt es eine Möglichkeit, den Index zu ändern, so dass ich zuerst durch den Betreff zugreifen?

Antwort

1

Verwenden loc zur Auswahl - zuerst von Niveau MultiIndex und dann nach Spaltennamen oder xs für einfache Auswahl implementiert:

df = df.loc['Subject_1', 'x_acc'] 
print (df) 
0 1502 
1 1667 
2 1611 
3 1601 
4 1643 
Name: x_acc, dtype: int64 

df = df.xs('Subject_1') 
print (df) 
    x_acc y_acc z_acc 
0 1502 2215 2153 
1 1667 2072 2047 
2 1611 1957 1906 
3 1601 1939 1831 
4 1643 1965 1879 

Und für komplizierte Auswahlen verwenden slicers:

idx = pd.IndexSlice 

df = df.loc['Subject_1', idx['x_acc','y_acc']] 
print (df) 
    x_acc y_acc 
0 1502 2215 
1 1667 2072 
2 1611 1957 
3 1601 1939 
4 1643 1965 

Es scheint auch, dass Ihr Code durch read_csv:

vereinfacht werden sollte
d_ = dict() 
DATA_ROOT = "../sample_data/chest_mounted/" 
cutoff_min = 0 
for fileName in os.listdir(DATA_ROOT): 
    if ".csv" in fileName and '.swp' not in fileName: 
     subj_key = "Subject_" + str(fileName.split(".")[0]) 
     d_[subj_key] = pd.read_csv(fileName, names=['x_acc', 'y_acc', 'z_acc']) 

df = pd.concat(d_) 
+0

genial! Vielen Dank, es hat funktioniert. Auch schön, re: read_csv es war viel schneller als das, was ich tat – user49593

Verwandte Themen