Añadir una fila a pandas DataFrame

Entiendo que los pandas están diseñados para cargar un DataFrame completamente poblado, pero necesito crear un DataFrame vacío y luego agregar filas, una por una . Cuál es la mejor manera de hacer esto ?

He creado con éxito un DataFrame vacío con:

 res = DataFrame(columns=('lib', 'qty1', 'qty2')) 

Luego puedo agregar una nueva fila y rellenar un campo con:

 res = res.set_value(len(res), 'qty1', 10.0) 

Funciona pero parece muy extraño: – / (falla al agregar valor de cadena)

¿Cómo puedo agregar una nueva fila a mi DataFrame (con tipo de columnas diferentes)?

 >>> import pandas as pd >>> import numpy as np >>> df = pd.DataFrame(columns=['lib', 'qty1', 'qty2']) >>> for i in range(5): >>> df.loc[i] = [np.random.randint(-1,1) for n in range(3)] >>> >>> print(df) lib qty1 qty2 0 0 0 -1 1 -1 -1 1 2 1 -1 1 3 0 0 0 4 1 -1 -1 [5 rows x 3 columns] 

En caso de que pueda obtener todos los datos para el dataframe por adelantado, hay un enfoque mucho más rápido que agregar a un dataframe:

  1. Cree una lista de diccionarios en los que cada diccionario corresponda a una fila de datos de entrada.
  2. Crear un dataframe de esta lista.

Tuve una tarea similar para la cual agregar un fotogtwig a fila de datos tomó 30 minutos, y crear un dataframe a partir de una lista de diccionarios completada en segundos.

 rows_list = [] for row in input_rows: dict1 = {} # get input row in dictionary format # key = col_name dict1.update(blah..) rows_list.append(dict1) df = pd.DataFrame(rows_list) 

Podría usar pandas.concat() o DataFrame.append() . Para detalles y ejemplos, vea Combinar, unir y concatenar .

Si conoce el número de entradas ex ante, debe preasignar el espacio proporcionando también el índice (tomando el ejemplo de datos de una respuesta diferente):

 import pandas as pd import numpy as np # we know we're gonna have 5 rows of data numberOfRows = 5 # create dataframe df = pd.DataFrame(index=np.arange(0, numberOfRows), columns=('lib', 'qty1', 'qty2') ) # now fill it up row by row for x in np.arange(0, numberOfRows): #loc or iloc both work here since the index is natural numbers df.loc[x] = [np.random.randint(-1,1) for n in range(3)] In[23]: df Out[23]: lib qty1 qty2 0 -1 -1 -1 1 0 0 0 2 -1 0 -1 3 0 -1 0 4 -1 0 0 

Comparación de velocidad

 In[30]: %timeit tryThis() # function wrapper for this answer In[31]: %timeit tryOther() # function wrapper without index (see, for example, @fred) 1000 loops, best of 3: 1.23 ms per loop 100 loops, best of 3: 2.31 ms per loop 

Y, a partir de los comentarios, con un tamaño de 6000, la diferencia de velocidad es aún mayor:

Aumentar el tamaño de la matriz (12) y el número de filas (500) hace que la diferencia de velocidad sea más sorprendente: 313 ms frente a 2,29 s.

Para una adición eficiente, vea Cómo agregar una fila adicional a un dataframe de pandas y Configuración con ampliación .

Agregue filas a través de loc/ix en datos de índice de clave no existentes . p.ej :

 In [1]: se = pd.Series([1,2,3]) In [2]: se Out[2]: 0 1 1 2 2 3 dtype: int64 In [3]: se[5] = 5. In [4]: se Out[4]: 0 1.0 1 2.0 2 3.0 5 5.0 dtype: float64 

O:

 In [1]: dfi = pd.DataFrame(np.arange(6).reshape(3,2), .....: columns=['A','B']) .....: In [2]: dfi Out[2]: AB 0 0 1 1 2 3 2 4 5 In [3]: dfi.loc[:,'C'] = dfi.loc[:,'A'] In [4]: dfi Out[4]: ABC 0 0 1 0 1 2 3 2 2 4 5 4 In [5]: dfi.loc[3] = 5 In [6]: dfi Out[6]: ABC 0 0 1 0 1 2 3 2 2 4 5 4 3 5 5 5 
 mycolumns = ['A', 'B'] df = pd.DataFrame(columns=mycolumns) rows = [[1,2],[3,4],[5,6]] for row in rows: df.loc[len(df)] = row 

Puede agregar una sola fila como diccionario usando la opción ignore_index .

 >>> f = pandas.DataFrame(data = {'Animal':['cow','horse'], 'Color':['blue', 'red']}) >>> f Animal Color 0 cow blue 1 horse red >>> f.append({'Animal':'mouse', 'Color':'black'}, ignore_index=True) Animal Color 0 cow blue 1 horse red 2 mouse black 

Ha pasado mucho tiempo, pero también me enfrenté al mismo problema. Y encontré aquí muchas respuestas interesantes. Así que estaba confundido qué método utilizar.

En el caso de agregar muchas filas al dataframe, me interesa la velocidad de rendimiento . Así que probé los 3 métodos más populares y comprobé su velocidad.

ACTUALIZADO EN 2019 usando nuevas versiones de paquetes

RENDIMIENTO DE VELOCIDAD

  1. Usando .append ( respuesta de NPE )
  2. Usando .loc ( la respuesta de fred y la respuesta de FooBar )
  3. Usando dict y crea DataFrame al final ( la respuesta de ShikharDua )

Resultados (en segundos):

 Adding 1000 rows 5000 rows 10000 rows .append 0.69 3.37 6.77 .loc 0.73 3.87 8.14 dict 0.011 0.046 0.088 

También gracias a @krassowski por su comentario útil, actualicé el código.

Así que uso la adición a través del diccionario para mí.


Código:

 import pandas import numpy import time #%% del df1, df2, df3 numOfRows = 1000 startTime = time.perf_counter() df1 = pandas.DataFrame(numpy.random.randint(100, size=(5,5)), columns=['A', 'B', 'C', 'D', 'E']) for i in range( 1,numOfRows-4): df1 = df1.append( dict( (a,numpy.random.randint(100)) for a in ['A','B','C','D','E']), ignore_index=True) print('Elapsed time: {:6.3f} seconds for {:d} rows'.format(time.perf_counter() - startTime, numOfRows)) print(df1.shape) startTime = time.perf_counter() df2 = pandas.DataFrame(numpy.random.randint(100, size=(5,5)), columns=['A', 'B', 'C', 'D', 'E']) for i in range( 1,numOfRows): df2.loc[i] = numpy.random.randint(100, size=(1,5))[0] print('Elapsed time: {:6.3f} seconds for {:d} rows'.format(time.perf_counter() - startTime, numOfRows)) print(df2.shape) startTime = time.perf_counter() row_list = [] for i in range (0,5): row_list.append(dict( (a,numpy.random.randint(100)) for a in ['A','B','C','D','E'])) for i in range( 1,numOfRows-4): dict1 = dict( (a,numpy.random.randint(100)) for a in ['A','B','C','D','E']) row_list.append(dict1) df3 = pandas.DataFrame(row_list, columns=['A','B','C','D','E']) print('Elapsed time: {:6.3f} seconds for {:d} rows'.format(time.perf_counter() - startTime, numOfRows)) print(df3.shape) 

PD: Creo que mi realización no es perfecta, y tal vez haya alguna optimización.

Por el bien de la manera Pythonic, aquí agregue mi respuesta:

 res = pd.DataFrame(columns=('lib', 'qty1', 'qty2')) res = res.append([{'qty1':10.0}], ignore_index=True) print(res.head()) lib qty1 qty2 0 NaN 10.0 NaN 

Esta no es una respuesta a la pregunta de OP, sino un ejemplo de juguete para ilustrar la respuesta de @ShikharDua que he encontrado muy útil.

Si bien este fragmento es trivial, en los datos reales tenía miles de filas y muchas columnas, y deseaba poder agrupar por columnas diferentes y luego realizar las estadísticas a continuación para más de una columna de taget. Por lo tanto, contar con un método confiable para construir el dataframe una fila a la vez fue una gran conveniencia. Gracias @ShikharDua!

 import pandas as pd BaseData = pd.DataFrame({ 'Customer' : ['Acme','Mega','Acme','Acme','Mega','Acme'], 'Territory' : ['West','East','South','West','East','South'], 'Product' : ['Econ','Luxe','Econ','Std','Std','Econ']}) BaseData columns = ['Customer','Num Unique Products', 'List Unique Products'] rows_list=[] for name, group in BaseData.groupby('Customer'): RecordtoAdd={} #initialise an empty dict RecordtoAdd.update({'Customer' : name}) # RecordtoAdd.update({'Num Unique Products' : len(pd.unique(group['Product']))}) RecordtoAdd.update({'List Unique Products' : pd.unique(group['Product'])}) rows_list.append(RecordtoAdd) AnalysedData = pd.DataFrame(rows_list) print('Base Data : \n',BaseData,'\n\n Analysed Data : \n',AnalysedData) 

También puede crear una lista de listas y convertirla en un dataframe.

 import pandas as pd rows = [] columns = ['i','double','square'] for i in range(6): row = [i, i*2, i*i] rows.append(row) df = pd.DataFrame(rows, columns=columns) 

dando

     yo doble cuadrado
 0 0 0 0
 1 1 2 1
 2 2 4 4
 3 3 6 9
 4 4 8 16
 5 5 10 25

Descubrió una manera simple y agradable:

 >>> df ABC one 1 2 3 >>> df.loc["two"] = [4,5,6] >>> df ABC one 1 2 3 two 4 5 6 

Cree un nuevo registro (dataframe) y añádalo a old_data_frame .
pase la lista de valores y los nombres de columna correspondientes para crear un nuevo_record (data_frame)

 new_record = pd.DataFrame([[0,'abcd',0,1,123]],columns=['a','b','c','d','e']) old_data_frame = pd.concat([old_data_frame,new_record]) 

Esta es la forma de agregar / agregar una fila en el dataframe de pandas

 def add_row(df, row): df.loc[-1] = row df.index = df.index + 1 return df.sort_index() add_row(df, [1,2,3]) 

Se puede usar para insertar / agregar una fila en pandas vacías o pobladas. DataFrame

Otra forma de hacerlo (probablemente no muy performante):

 # add a row def add_row(df, row): colnames = list(df.columns) ncol = len(colnames) assert ncol == len(row), "Length of row must be the same as width of DataFrame: %s" % row return df.append(pd.DataFrame([row], columns=colnames)) 

También puede mejorar la clase DataFrame de esta manera:

 import pandas as pd def add_row(self, row): self.loc[len(self.index)] = row pd.DataFrame.add_row = add_row 

Hazlo simple. Al tomar la lista como entrada, que se agregará como fila en el dataframe:

 import pandas as pd res = pd.DataFrame(columns=('lib', 'qty1', 'qty2')) for i in range(5): res_list = list(map(int, input().split())) res = res.append(pd.Series(res_list,index=['lib','qty1','qty2']), ignore_index=True) 
 import pandas as pd t1=pd.DataFrame() for i in range(len(the number of rows)): #add rows as columns t1[i]=list(rows) t1=t1.transpose() t1.columns=list(columns) 

Esto se encargará de agregar un elemento a un DataFrame vacío. El problema es que df.index.max () == nan para el primer índice:

 df = pd.DataFrame(columns=['timeMS', 'accelX', 'accelY', 'accelZ', 'gyroX', 'gyroY', 'gyroZ']) df.loc[0 if math.isnan(df.index.max()) else df.index.max() + 1] = [x for x in range(7)]