He manipulado algunos datos usando pandas y ahora quiero llevar a cabo un lote de nuevo en la base de datos. Esto requiere que convierta el marco de datos en una matriz de tuplas, con cada tupla correspondiente a una "fila" del marco de datos.
Mi DataFrame se parece a:
In [182]: data_set
Out[182]:
index data_date data_1 data_2
0 14303 2012-02-17 24.75 25.03
1 12009 2012-02-16 25.00 25.07
2 11830 2012-02-15 24.99 25.15
3 6274 2012-02-14 24.68 25.05
4 2302 2012-02-13 24.62 24.77
5 14085 2012-02-10 24.38 24.61
Quiero convertirlo en una serie de tuplas como:
[(datetime.date(2012,2,17),24.75,25.03),
(datetime.date(2012,2,16),25.00,25.07),
...etc. ]
¿Alguna sugerencia sobre cómo puedo hacer esto de manera eficiente?
list(df.itertuples(index=False, name=None))
df.to_records(index=False)
y una lista de dictados:df.to_dict('records')
Respuestas:
Qué tal si:
para pandas <0.24 uso
fuente
.itertuples
, que será más eficiente que obtener los valores como una matriz y convertirlos en una tupla.A partir del 17.1, lo anterior devolverá una lista de tuplas nombradas .
Si desea una lista de tuplas ordinarias, pase
name=None
como argumento:fuente
tuple
en suzip
iterador (en lugar denamedtuple
s), llame al:data_set.itertuples(index=False, name=None)
itertuples
es lento . Evitar si es posible. Para los bucles (como se muestra la respuesta aceptada) suele ser más rápido en estos casos.Una forma genérica:
fuente
data_set.to_records(index=False).tolist()
mejor?Motivación
Muchos conjuntos de datos son lo suficientemente grandes como para que tengamos que preocuparnos por la velocidad / eficiencia. Entonces ofrezco esta solución con ese espíritu. Sucede que también es sucinto.
En aras de la comparación, dejemos caer la
index
columnaSolución
Propondré el uso de
zip
ymap
Resulta que también es flexible si quisiéramos tratar con un subconjunto específico de columnas. Asumiremos que las columnas que ya hemos mostrado son el subconjunto que queremos.
¿Qué es más rápido?
El
records
desvío es más rápido seguido de convergencia asintóticazipmap
yiter_tuples
Usaré una biblioteca
simple_benchmarks
que obtuve de esta publicaciónComprueba los resultados
fuente
Aquí hay un enfoque vectorizado (asumiendo el marco de datos,
data_set
que se definirá como en sudf
lugar) que devuelve unlist
detuples
como se muestra:produce:
La idea de establecer la columna de fecha y hora como el eje del índice es ayudar en la conversión del
Timestamp
valor a sudatetime.datetime
equivalente de formato correspondiente haciendo uso delconvert_datetime64
argumento en elDF.to_records
que lo hace para unDateTimeIndex
marco de datos.Esto devuelve un
recarray
que luego podría hacerse para devolver unlist
uso.tolist
La solución más generalizada según el caso de uso sería:
fuente
La forma más eficiente y fácil:
Puede filtrar las columnas que necesita antes de esta llamada.
fuente
Esta respuesta no agrega ninguna respuesta que aún no se haya discutido, pero aquí hay algunos resultados de velocidad. Creo que esto debería resolver las preguntas que surgieron en los comentarios. Todos estos parecen ser O (n) , basados en estos tres valores.
TL; DR :
tuples = list(df.itertuples(index=False, name=None))
ytuples = list(zip(*[df[c].values.tolist() for c in df]))
están empatados para el más rápido.Hice una prueba de velocidad rápida en los resultados de tres sugerencias aquí:
tuples = list(zip(*[df[c].values.tolist() for c in df]))
tuples = [tuple(x) for x in df.values]
name=None
sugerencia de @Axel:tuples = list(df.itertuples(index=False, name=None))
Talla pequeña:
Da:
Más grande:
Da:
Tanta paciencia como tengo:
Da:
La versión zip y la versión itertuples están dentro de los intervalos de confianza entre sí. Sospecho que están haciendo lo mismo debajo del capó.
Sin embargo, estas pruebas de velocidad son probablemente irrelevantes. Llevar los límites de la memoria de mi computadora no lleva una gran cantidad de tiempo, y realmente no deberías estar haciendo esto en un gran conjunto de datos. Trabajar con esas tuplas después de hacer esto terminará siendo realmente ineficiente. Es poco probable que sea un cuello de botella importante en su código, por lo tanto, quédese con la versión que cree que es más legible.
fuente
[*zip(*map(df.get, df))]
por algún tiempo ahora. De todos modos, pensé que lo encontraría interesante.fuente
Cambiar la lista de marcos de datos en una lista de tuplas.
fuente
Más forma pitónica:
fuente
map()
Es notoriamente no pitónico.