2017-11-07 2 views
1

ein Having DataFrame (oder Series) von Listen aus, wie folgt aussehen:Convert Dataframe oder Reihe von Listen in einer gestapelten Datenrahmen (oder Serie)

df = pd.DataFrame([[[1,3], [2,3,4], [1,4,2,5]]], columns=['A', 'B', 'C']).T 
print(df) 

Ausgang:

   0 
A  [1, 3] 
B  [2, 3, 4] 
C [1, 4, 2, 5] 

Wie kann ich verwandeln es in

0 
A 1 
A 2 
B 2 
B 3 
B 4 
C 1 
C 4 
C 2 
C 5 

ich habe versuchtzu verwenden 210 aber das hat nicht ganz funktioniert. Kann ich das implizit konvertieren? Ich habe auch versucht, alle Zahlen als Tupel [('A', 1), ('A', 3), ..] für from_records() zu extrahieren, aber ich konnte das auch nicht tun.

Ich denke, dass ich es so machen könnte:

pd.DataFrame.from_records(df[0].map(lambda x: [(0, v) for v in x]).sum()) 

aber ich weiß nicht, wie der Index für den Zugriff auf .. note (0, v) sollte eigentlich so etwas wie (x.index, v) sein.

Antwort

1

Need Werte in Spalte Abflachen und dann repeat Index durch len von lists:

df = pd.DataFrame({0:np.concatenate(df.iloc[:, 0].values.tolist())}, 
        index=df.index.repeat(df[0].str.len())) 

from itertools import chain 
df=pd.DataFrame({0:list(chain.from_iterable(df.iloc[:, 0].values.tolist()))}, 
       index=df.index.repeat(df[0].str.len())) 

print (df) 
    0 
A 1 
A 3 
B 2 
B 3 
B 4 
C 1 
C 4 
C 2 
C 5 

Timings:

np.random.seed(456) 

N = 100000 
a = [list(range(np.random.randint(5, 20))) for _ in range(N)] 
L = list('abcdefghijklmno') 
df = pd.DataFrame({0:a}, index=np.random.choice(L, size=N)) 
print (df) 

In [348]: %timeit pd.DataFrame({0:np.concatenate(df.iloc[:, 0].values.tolist())}, index=df.index.repeat(df[0].str.len())) 
1 loop, best of 3: 218 ms per loop 

In [349]: %timeit pd.DataFrame({0:list(chain.from_iterable(df[0].values.tolist()))}, index=df.index.repeat(df[0].str.len())) 
1 loop, best of 3: 388 ms per loop 

In [350]: %timeit pd.DataFrame(df.iloc[:, 0].tolist(), index=df.index).stack().reset_index(level=1, drop=1).to_frame().astype(int) 
1 loop, best of 3: 384 ms per loop 
+0

ich meine Frage mit einem Beispiel aktualisiert haben mit 'from_records()', das nur das Problem hat, dass ich nicht in der Lage bin der Zugriff auf aktueller Index jedes Elements, wenn ich 'map()' verwende .. irgendeine Idee, wenn es so funktionieren könnte? – displayname

+0

Hmmm, ist es nicht möglich auf diese Weise :( – jezrael

+0

Ist eine bessere Leistung erforderlich? – jezrael

1

Verwenden Sie die pd.DataFrame + stack + reset_index + to_frame:

df = pd.DataFrame(df.iloc[:, 0].tolist(), index=df.index)\ 
         .stack().reset_index(level=1, drop=1).to_frame() 
df 

    0 
A 1.0 
A 3.0 
B 2.0 
B 3.0 
B 4.0 
C 1.0 
C 4.0 
C 2.0 
C 5.0 
Verwandte Themen