python list pandas dataframe apply

python - ¿Por qué funciona df.apply(tuple) pero no df.apply(list)?



pandas dataframe (1)

Aquí hay un marco de datos:

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

Podría recuperar una columna que es básicamente una tupla de columnas del df original usando 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

Pero si quiero una lista de valores en lugar de una tupla de ellos, no puedo hacerlo, porque no me da lo que espero:

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

En cambio, necesito hacer:

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

¿Por qué no puedo usar df.apply(list, 1) para obtener lo que quiero?

Apéndice

Momentos de algunas posibles soluciones:

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


El culpable está here . Con func=tuple funciona, pero el uso de func=list genera una excepción desde el módulo compilado lib.reduce :

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

Como puede ver, atrapan la excepción pero no se molestan en manejarla.

Incluso sin la cláusula demasiado amplia, excepto, eso es un error en los pandas . Puede intentar subirlo a su rastreador, pero se han cerrado problemas similares con cierto sabor de wont-fix o dupe.

16321: comportamiento extraño usando la lista de creación apply () basada en las columnas actuales

15628: Dataframe.apply no siempre devuelve una Serie cuando reduce = True

Este último problema se cerró, luego se volvió a abrir y se convirtió en una solicitud de mejora de documentos hace algunos meses, y ahora parece estar siendo utilizado como un vertedero para cualquier problema relacionado.

Presumiblemente no es una alta prioridad porque, como comentó piRSquared (y uno de los mantenedores de pandas comentó lo mismo ), es mejor que comprenda la lista:

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

Por lo general, apply sería usar un ufunc numpy o similar.