Estoy comenzando con los documentos de Pandas DataFrame aquí: http://pandas.pydata.org/pandas-docs/stable/dsintro.html
Me gustaría llenar iterativamente el DataFrame con valores en un tipo de cálculo de serie temporal. Básicamente, me gustaría inicializar el DataFrame con columnas A, B y filas de marca de tiempo, todas 0 o todas NaN.
Luego agregaría valores iniciales y revisaría estos datos calculando la nueva fila de la fila anterior, digamos más row[A][t] = row[A][t-1]+1
o menos.
Actualmente estoy usando el código de la siguiente manera, pero siento que es un poco feo y debe haber una manera de hacer esto con un DataFrame directamente, o simplemente una mejor manera en general. Nota: estoy usando Python 2.7.
import datetime as dt
import pandas as pd
import scipy as s
if __name__ == '__main__':
base = dt.datetime.today().date()
dates = [ base - dt.timedelta(days=x) for x in range(0,10) ]
dates.sort()
valdict = {}
symbols = ['A','B', 'C']
for symb in symbols:
valdict[symb] = pd.Series( s.zeros( len(dates)), dates )
for thedate in dates:
if thedate > dates[0]:
for symb in valdict:
valdict[symb][thedate] = 1+valdict[symb][thedate - dt.timedelta(days=1)]
print valdict
.append
en pd y agregar una lista? Sé que.append
en pandas copia todo el conjunto de datos a un nuevo objeto ´, ¿las pitones agregadas funcionan de manera diferente?Respuestas:
Aquí hay un par de sugerencias:
Uso
date_range
para el índice:Nota: podríamos crear un DataFrame vacío (con
NaN
s) simplemente escribiendo:Para hacer este tipo de cálculos para los datos, use una matriz numpy:
Por lo tanto, podemos crear el DataFrame:
fuente
index
x0
dimensiones (columns = []
), y adjuntar una columna en cada vuelta de un ciclo. Quiero decirdf[col_name] = pandas.Series([...])
en un bucle iterando a través de los nombres de columna. En el primer caso, no solo la asignación de memoria lleva tiempo, sino que reemplazar NaNs con nuevos valores parece extremadamente lento.Si simplemente desea crear un marco de datos vacío y llenarlo con algunos marcos de datos entrantes más tarde, intente esto:
En este ejemplo, estoy usando este documento de pandas para crear un nuevo marco de datos y luego estoy usando append para escribir en newDF con datos de oldDF.
Si tengo que seguir agregando nuevos datos a este nuevo DF desde más de un viejo DF, solo uso un bucle for para iterar sobre pandas.DataFrame.append ()
fuente
append
(y de manera similarconcat
) copia el conjunto de datos completo a un nuevo objeto cada vez, por lo tanto, iterar y agregar puede causar un gran impacto en el rendimiento. Para obtener más información, consulte: pandas.pydata.org/pandas-docs/stable/merging.htmlThe Right Way ™ para crear un marco de datos
La mayoría de las respuestas aquí le dirán cómo crear un DataFrame vacío y completarlo, pero nadie le dirá que es algo malo.
Aquí está mi consejo: espere hasta estar seguro de tener todos los datos con los que necesita trabajar. Use una lista para recopilar sus datos, luego inicialice un DataFrame cuando esté listo.
Siempre es más barato agregar a una lista y crear un DataFrame de una vez que crear un DataFrame vacío (o uno de los NaN) y agregarlo una y otra vez. Las listas también ocupan menos memoria y son una estructura de datos mucho más liviana para trabajar , agregar y eliminar (si es necesario).
La otra ventaja de este método
dtypes
se infiere automáticamente (en lugar de asignarlosobject
a todos).La última ventaja es que a
RangeIndex
se crea automáticamente para sus datos , por lo que es una cosa menos de qué preocuparse (eche un vistazo a los pobresappend
y losloc
métodos a continuación, verá elementos en ambos que requieren el manejo adecuado del índice).Cosas que NO debes hacer
append
oconcat
dentro de un bucleAquí está el error más grande que he visto de los principiantes:
La memoria se reasigna para cada
append
uconcat
operación que tiene. Combine esto con un bucle y tendrá una operación de complejidad cuadrática . Desde ladf.append
página del documento :El otro error asociado
df.append
es que los usuarios tienden a olvidar que agregar no es una función in situ , por lo que el resultado debe asignarse de nuevo. También debes preocuparte por los tipos:Tratar con columnas de objetos nunca es algo bueno, porque los pandas no pueden vectorizar las operaciones en esas columnas. Deberá hacer esto para solucionarlo:
loc
dentro de un bucleTambién he visto que se
loc
solía agregar a un DataFrame que se creó vacío:Como antes, no ha asignado previamente la cantidad de memoria que necesita cada vez, por lo que la memoria vuelve a crecer cada vez que crea una nueva fila . Es tan malo como
append
, y aún más feo.Marco de datos vacío de NaN
Y luego, está creando un DataFrame de NaNs, y todas las advertencias asociadas con él.
Crea un DataFrame de columnas de objetos, como los demás.
Anexar todavía tiene todos los problemas como los métodos anteriores.
La prueba está en el pudín
El cronometraje de estos métodos es la forma más rápida de ver cuánto difieren en términos de su memoria y utilidad.
Código de referencia para referencia.
fuente
Inicializar marco vacío con nombres de columna
Agregar un nuevo registro a un marco
También es posible que desee pasar un diccionario:
Agregue otro marco a su marco existente
Consideraciones de rendimiento
Si agrega filas dentro de un bucle, considere los problemas de rendimiento. Para los primeros 1000 registros, el rendimiento de "my_df.loc" es mejor, pero gradualmente se vuelve más lento al aumentar el número de registros en el bucle.
Si planea hacer cosas finas dentro de un gran bucle (digamos 10M de registros más o menos), es mejor que use una mezcla de estos dos; llene un marco de datos con iloc hasta que el tamaño sea de alrededor de 1000, luego agréguelo al marco de datos original y vacíe el marco de datos temporal. Esto aumentaría tu rendimiento unas 10 veces.
fuente
my_df = my_df.append(my_df2)
no funciona para mí a menos que especifiqueignore_index=True
.Asumir un marco de datos con 19 filas
Mantener la columna A como constante
Mantener la columna b como una variable dada por un bucle
Puede reemplazar la primera x
pd.Series([x], index = [x])
con cualquier valorfuente