Saltar al contenido

¿Crear un Pandas DataFrame vacío y luego llenarlo?

Revisamos de forma completamente cada escrito de nuestra página web con la meta de mostrarte siempre información veraz y certera.

Solución:

He aquí un par de sugerencias:

Utilizar date_range para el índice:

import datetime
import pandas as pd
import numpy as np

todays_date = datetime.datetime.now().date()
index = pd.date_range(todays_date-datetime.timedelta(10), periods=10, freq='D')

columns = ['A','B', 'C']

Nota: podríamos crear un DataFrame vacío (con NaNs) simplemente escribiendo:

df_ = pd.DataFrame(index=index, columns=columns)
df_ = df_.fillna(0) # with 0s rather than NaNs

Para hacer este tipo de cálculos para los datos, use un numpy array:

data = np.array([np.arange(10)]*3).T

Por lo tanto, podemos crear el DataFrame:

In [10]: df = pd.DataFrame(data, index=index, columns=columns)

In [11]: df
Out[11]: 
            A  B  C
2012-11-29  0  0  0
2012-11-30  1  1  1
2012-12-01  2  2  2
2012-12-02  3  3  3
2012-12-03  4  4  4
2012-12-04  5  5  5
2012-12-05  6  6  6
2012-12-06  7  7  7
2012-12-07  8  8  8
2012-12-08  9  9  9

¡NUNCA haga crecer un DataFrame!

TLDR; (Solo lee el texto en negrita)

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: Acumule datos en una lista, no en un DataFrame.

Use una lista para recopilar sus datos, luego inicialice un DataFrame cuando esté listo. Funcionará un formato de lista de listas o de lista de dictados, pd.DataFrame acepta ambos.

data = []
for a, b, c in some_function_that_yields_data():
    data.append([a, b, c])

df = pd.DataFrame(data, columns=['A', 'B', 'C'])

Ventajas de este enfoque:

  1. Siempre es más barato agregar a una lista y crear un DataFrame de una sola vez que crear un DataFrame vacío (o uno de NaN) y agregarlo una y otra vez.

  2. 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).

  3. dtypes se infieren automáticamente (en lugar de asignar object a todos ellos).

  4. A RangeIndex se crea automáticamente para sus datosen lugar de tener que tener cuidado de asignar el índice correcto a la fila que está agregando en cada iteración.

Si aún no está convencido, esto también se menciona en la documentación:

Agregar filas iterativamente a un DataFrame puede ser más intensivo desde el punto de vista computacional que una sola concatenación. Una mejor solución es agregar esas filas a una lista y luego concatenar la lista con el DataFrame original, todo a la vez.

Pero, ¿qué sucede si mi función devuelve tramas de datos más pequeñas que necesito combinar en una trama de datos grande?

Está bien, aún puede hacer esto en tiempo lineal al hacer crecer o crear una lista de python de DataFrames más pequeños, luego llamar pd.concat.

small_dfs = []
for small_df in some_function_that_yields_dataframes():
    small_dfs.append(small_df)

large_df = pd.concat(small_dfs, ignore_index=True)

o, más concisamente:

large_df = pd.concat(
    list(some_function_that_yields_dataframes()), ignore_index=True)


Estas opciones son horribles

append o concat dentro de un bucle

Aquí está el error más grande que he visto de los principiantes:

df = pd.DataFrame(columns=['A', 'B', 'C'])
for a, b, c in some_function_that_yields_data():
    df = df.append('A': i, 'B': b, 'C': c, ignore_index=True) # yuck
    # or similarly,
    # df = pd.concat([df, pd.Series('A': i, 'B': b, 'C': c)], ignore_index=True)

La memoria se reasigna para cada append o concat operación que tienes. Combina esto con un bucle y tienes un operación de complejidad cuadrática.

El otro error asociado con df.append es que los usuarios tienden a olvidar agregar no es una función en el lugar, por lo que el resultado debe volver a asignarse. También tienes que preocuparte por los dtypes:

df = pd.DataFrame(columns=['A', 'B', 'C'])
df = df.append('A': 1, 'B': 12.3, 'C': 'xyz', ignore_index=True)

df.dtypes
A     object   # yuck!
B    float64
C     object
dtype: object

Tratar con columnas de objetos nunca es bueno, porque los pandas no pueden vectorizar operaciones en esas columnas. Deberá hacer esto para solucionarlo:

df.infer_objects().dtypes
A      int64
B    float64
C     object
dtype: object

loc dentro de un bucle

yo también he visto loc se usa para agregar a un DataFrame que se creó vacío:

df = pd.DataFrame(columns=['A', 'B', 'C'])
for a, b, c in some_function_that_yields_data():
    df.loc[len(df)] = [a, b, c]

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 appendy aún más feo.

Trama de datos vacía de NaN

Y luego, está la creación de un marco de datos de NaN y todas las advertencias asociadas con él.

df = pd.DataFrame(columns=['A', 'B', 'C'], index=range(5))
df
     A    B    C
0  NaN  NaN  NaN
1  NaN  NaN  NaN
2  NaN  NaN  NaN
3  NaN  NaN  NaN
4  NaN  NaN  NaN

Crea un DataFrame de columnas de objetos, como los demás.

df.dtypes
A    object  # you DON'T want this
B    object
C    object
dtype: object

Agregar todavía tiene todos los problemas que los métodos anteriores.

for i, (a, b, c) in enumerate(some_function_that_yields_data()):
    df.iloc[i] = [a, b, c]


La prueba está en el pudín

Programar estos métodos es la forma más rápida de ver cuánto difieren en términos de memoria y utilidad.

ingrese la descripción de la imagen aquí

Código de evaluación comparativa para referencia.

Si simplemente desea crear un marco de datos vacío y llenarlo con algunos marcos de datos entrantes más tarde, intente esto:

newDF = pd.DataFrame() #creates a new dataframe that's empty
newDF = newDF.append(oldDF, ignore_index = True) # ignoring index is optional
# try printing some data from newDF
print newDF.head() #again optional 

En este ejemplo, estoy usando este documento de pandas para crear un nuevo marco de datos y luego uso agregar para escribir en el nuevo DF con datos del antiguo DF.

Si tengo que seguir agregando nuevos datos a este nuevo DF desde más de un DF antiguo, solo uso un bucle for para iterar sobre pandas.DataFrame.append()

Te mostramos las reseñas y valoraciones de los usuarios

Te invitamos a añadir valor a nuestra información aportando tu experiencia en las aclaraciones.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *