2017-08-28 22 views
6

Oto dataframe:Dlaczego df.apply (tuple) działa, ale nie df.apply (list)?

A B C 
0 6 2 -5 
1 2 5 2 
2 10 3 1 
3 -5 2 8 
4 3 6 2 

mogę odzyskać kolumnę, która jest w zasadzie krotki kolumn z oryginalnego df użyciu df.apply:

out = df.apply(tuple, 1) 
print(out) 

0 (6, 2, -5) 
1  (2, 5, 2) 
2 (10, 3, 1) 
3 (-5, 2, 8) 
4  (3, 6, 2) 
dtype: object 

Ale jeśli chcę listę wartości zamiast krotki z nich, nie moge tego zrobic, poniewaz nie daje mi to, czego sie spodziewam:

out = df.apply(list, 1) 
print(out) 

    A B C 
0 6 2 -5 
1 2 5 2 
2 10 3 1 
3 -5 2 8 
4 3 6 2 

Zamiast tego, nie jestem d robić:

out = pd.Series(df.values.tolist()) 
print(out) 

0 [6, 2, -5] 
1  [2, 5, 2] 
2 [10, 3, 1] 
3 [-5, 2, 8] 
4  [3, 6, 2] 
dtype: object 

Dlaczego nie mogę korzystać df.apply(list, 1) aby dostać to, co chcę?


Dodatek

Timings niektórych możliwych obejściach:

df_test = pd.concat([df] * 10000, 0) 

%timeit pd.Series(df.values.tolist()) # original workaround 
10000 loops, best of 3: 161 µs per loop 

%timeit df.apply(tuple, 1).apply(list, 1) # proposed by Alexander 
1000 loops, best of 3: 615 µs per loop 
+0

Dziwne zachowanie. 'df.apply (tuple, 1) .apply (list)' jako obejście? – Alexander

+0

@Alexander Możliwe, ale powolne. :(Dodano pewne taktowanie –

+3

W momencie, w którym masz DataFrame obiektów list-list, porzuciłeś wszelką nadzieję na szybkość i wydajność w każdym razie ... Uwaga, '.apply' jest po prostu otoką wokół Pythona dla -lub, więc po prostu użyj 'iterrows' z pętlą for, która prawdopodobnie będzie * szybsza * niż w podejściu' .apply'. –

Odpowiedz

3

winowajcą jest here. Z func=tuple to działa, ale przy użyciu func=list podnosi wyjątek od wewnątrz skompilowanego modułu lib.reduce:

ValueError: ('function does not reduce', 0) 

Jak widać, ich złapać wyjątek, ale nie przejmuj się nią.

Nawet bez zbyt szerokiej, z wyjątkiem klauzuli, to błąd w pandach. Możesz spróbować podnieść go na swoim trackerze, ale podobne problemy zostały zamknięte z pewnym smakiem wont-fix lub dupe.

16321: weird behavior using apply() creating list based on current columns

15628: Dataframe.apply does not always return a Series when reduce=True

Ten ostatni problem został zamknięty, a następnie ponownie, i przekształcony na zamówienie akcesorium docs kilka miesięcy temu, a teraz wydaje się być używany jako wysypiskiem wszelkich zagadnień pokrewnych.

Przypuszczalnie nie jest to priorytet, bo jak piRSquared commented (i jeden z opiekunów pand commented the same), jesteś lepiej z listowego:

pd.Series([list(x) for x in df.itertuples(index=False)]) 

Zazwyczaj apply byłyby wykorzystaniem numpy ufunc lub podobny .

+0

Dzięki za pakiet. zajrzyj do tych linków. –

Powiązane problemy