2016-05-09 24 views
1

Ich habe einen Pandas Datenrahmen mit einer Spalte Listen mit Objektenaccesing jedes erstes Element der Pandas Dataframe-Spalte enthält Listen

 A 
0 [1,2] 
1 [3,4] 
2 [8,9] 
3 [2,6] 

Wie kann ich das erste Element jeder Liste zuzugreifen und sie in eine neue Spalte der speichern Datenrahmen? Um ein Ergebnis wie dieses

 A  new_col 
0 [1,2]  1 
1 [3,4]  3 
2 [8,9]  8 
3 [2,6]  2 

zu bekommen Ich weiß, das über jede Zeile über das Iterieren getan werden könnte, aber gibt es eine „pythonic“ Art und Weise?

Antwort

2

Sie map und eine lambda Funktion

df.loc[:, 'new_col'] = df.A.map(lambda x: x[0]) 

+0

in meinem Fall hatte der Code die kürzeste Laufzeit mit Ihrer Lösung. Danke für die Hilfe! – mkoala

1

Verwendung apply mit x[0]:

df['new_col'] = df.A.apply(lambda x: x[0]) 
print df 
     A new_col 
0 [1, 2]  1 
1 [3, 4]  3 
2 [8, 9]  8 
3 [2, 6]  2 
3

Wie immer verwenden können, denken Sie daran, dass nicht-skalare Objekte in Bildern zu speichern ist in der Regel benachteiligt, und sollte eigentlich nur als temporärer Zwischenschritt verwendet werden.

Das heißt, können Sie die .str Accessor auch verwenden, obwohl es keine Spalte von Strings ist:

>>> df = pd.DataFrame({"A": [[1,2],[3,4],[8,9],[2,6]]}) 
>>> df["new_col"] = df["A"].str[0] 
>>> df 
     A new_col 
0 [1, 2]  1 
1 [3, 4]  3 
2 [8, 9]  8 
3 [2, 6]  2 
>>> df["new_col"] 
0 1 
1 3 
2 8 
3 2 
Name: new_col, dtype: int64 
+0

Das war wirklich nur vorübergehend, weil ich '.split()' auf den Strings in diesen Spalten verwendet habe. Danke für deine schnelle Hilfe! – mkoala

1

Sie können nur eine bedingte Liste Verständnis verwenden, die den ersten Wert eines iterable nimmt oder sonst verwendet keine für dieser Gegenstand. List Comprehensions sind sehr Pythonic.

df['new_col'] = [val[0] if hasattr(val, '__iter__') else None for val in df["A"]] 

>>> df 
     A new_col 
0 [1, 2]  1 
1 [3, 4]  3 
2 [8, 9]  8 
3 [2, 6]  2 

Timings

df = pd.concat([df] * 10000) 

%timeit df['new_col'] = [val[0] if hasattr(val, '__iter__') else None for val in df["A"]] 
100 loops, best of 3: 13.2 ms per loop 

%timeit df["new_col"] = df["A"].str[0] 
100 loops, best of 3: 15.3 ms per loop 

%timeit df['new_col'] = df.A.apply(lambda x: x[0]) 
100 loops, best of 3: 12.1 ms per loop 

%timeit df.A.map(lambda x: x[0]) 
100 loops, best of 3: 11.1 ms per loop 

die Sicherheitsüberprüfung zu gewährleisten einen interable entfernen.

%timeit df['new_col'] = [val[0] for val in df["A"]] 
100 loops, best of 3: 7.38 ms per loop