Cree un marco de datos de Pandas agregando una fila a la vez

1161

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

Creé con éxito un DataFrame vacío con:

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

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

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

Funciona, pero parece muy extraño: - / (falla al agregar un valor de cadena).

¿Cómo puedo agregar una nueva fila a mi DataFrame (con un tipo de columna diferente)?

7
  • 78
    Tenga en cuenta que esta es una forma muy ineficiente de construir un DataFrame grande; se deben crear nuevas matrices (copiando los datos existentes) cuando agrega una fila. Wes McKinney 23 de mayo de 2012 a las 13:46
  • 6
    @WesMcKinney: Gracias, es muy bueno saberlo. ¿Es muy rápido agregar columnas a tablas enormes? max 28 de agosto de 2012 a las 4:27
  • 5
    Si es demasiado ineficaz para usted, puede preasignar una fila adicional y luego actualizarla. user1154664 19/04/2013 a las 19:54
  • 19
    Oye tú ... sí, ... veo lo que estás haciendo ... quieres ejecutar esto dentro de un bucle y agregar filas iterativamente a un DataFrame vacío, ¿no es así ... bueno, no? t! cs95 13/07/20 a las 12:52
  • 2
    Puedo entender que esto puede ser incorrecto en general, pero, ¿qué pasa con el procesamiento en tiempo real? Entonces, digamos que tengo algunos datos que vienen cada segundo y tengo un hilo que solo quiere llenar un marco de datos y tener otro hilo uniforme que va y mira el marco de datos. Encuentro este caso de uso válido y donde esa solución es aplicable aGiuseppe 20 nov.20 a las 17:24
785

Puede usar df.loc[i], donde la fila con índice iserá la que especifique en el marco de datos.

>>> import pandas as pd
>>> from numpy.random import randint

>>> df = pd.DataFrame(columns=['lib', 'qty1', 'qty2'])
>>> for i in range(5):
>>>     df.loc[i] = ['name' + str(i)] + list(randint(10, size=2))

>>> df
     lib qty1 qty2
0  name0    3    3
1  name1    2    4
2  name2    2    8
3  name3    2    1
4  name4    9    6
7
  • 34
    Considere agregar el índice para preasignar memoria (vea mi respuesta)FooBar 23 de julio de 2014 a las 14:22
  • 56
    .lochace referencia a la columna de índice, por lo que si está trabajando con un DataFrame preexistente con un índice que no es una secuencia continua de enteros que comienzan con 0 (como en su ejemplo), .locsobrescribirá las filas existentes o insertará filas, o cree huecos en su índice. Un enfoque más robusto (pero no infalible) para agregar un marco de datos existente de longitud distinta de cero sería: df.loc[df.index.max() + 1] = [randint(...o rellenar previamente el índice como sugirió @FooBar. hobs 25 de septiembre de 2015 a las 23:21
  • 5
    @hobs df.index.max()es nancuando el DataFrame está vacío. flow2k 24 abr 2019 a las 1:30
  • 2
    @ flow2k buena captura! La única solución en la que puedo pensar es intentar aceptar (solo en la inserción de la primera fila) con una llamada al constructor pd.DataFrame (). ¿Conoces alguna forma mejor? hobs 24/04/19 a las 21:31
  • 12
    @hobs Una solución en la que pensé es usar el operador ternario:df.loc[0 if pd.isnull(df.index.max()) else df.index.max() + 1]flow2k 25/04/19 a las 21:17
653

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

  1. Cree una lista de diccionarios en la que cada diccionario corresponde a una fila de datos de entrada.
  2. Cree un marco de datos de esta lista.

Tuve una tarea similar para la cual agregar un marco de datos fila por fila tomó 30 minutos y crear un marco de datos a partir de una lista de diccionarios completados 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)               
dieciséis
  • 63
    También he hecho esto para cualquier situación en la que no pueda obtener todos los datos por adelantado. La diferencia de velocidad es asombrosa. fantabolous 13/08/2014 a las 12:19
  • 63
    Copiando de pandas docs: It is worth noting however, that concat (and therefore append) makes a full copy of the data, and that constantly reusing this function can create a significant performance hit. If you need to use the operation over several datasets, use a list comprehension.( pandas.pydata.org/pandas-docs/stable/… )thikonom 25/12/15 a las 22:01
  • 7
    ¡Esto funciona muy bien! Excepto cuando creé el marco de datos, los nombres de las columnas estaban en el orden incorrecto ...user5359531 9 de agosto de 2016 a las 21:36
  • 5
    @ user5359531 Puede usar un dictado ordenado en ese casoShikharDua 10/08/2016 a las 20:31
  • 25
    @ user5359531 Puede especificar manualmente las columnas y se conservará el orden. pd.DataFrame (rows_list, columnas = ['C1', 'C2', 'C3']) hará el trucoMarcello Grechi Lins 27/01/17 a las 22:26
321

Podrías usar pandas.concat()o DataFrame.append(). Para obtener detalles y ejemplos, consulte Combinar, unir y concatenar .

4
  • 7
    Hola, entonces, ¿cuál es la respuesta para los métodos que usan append () o concat (). Tengo el mismo problema, pero sigo intentando resolverlo. notilas 20/0814 a las 22:52
  • 140
    Esta es la respuesta correcta, pero no es una muy buena respuesta (casi solo enlace). jwg 18 de mayo de 2016 a las 14:34
  • 5
    Creo que la respuesta de @fred es más correcta. IIUC, el problema con esta respuesta es que copia innecesariamente todo el DataFrame cada vez que se agrega una fila. Usar el .locmecanismo que se puede evitar, especialmente si tiene cuidado. Ken Williams 16 de marzo de 2017 a las 16:03
  • 7
    Pero si desea usar DataFrame.append(), debe asegurarse de que los datos de su fila también sean un DataFrame en primer lugar, no una lista. StayFoolish 8 de septiembre de 2017 a las 12:46
311

En el caso de agregar muchas filas al marco de datos, estoy interesado en el rendimiento . Así que probé los cuatro métodos más populares y verifiqué su velocidad.

Rendimiento

  1. Usando .append ( respuesta de NPE )
  2. Usando .loc ( respuesta de fred )
  3. Usando .loc con preasignación ( respuesta de FooBar )
  4. Usando dict y crea DataFrame al final ( respuesta de ShikharDua )

Resultados del tiempo de ejecución (en segundos):

Acercarse 1000 filas 5000 filas 10000 filas
.adjuntar 0,69 3.39 6,78
.loc sin prealloc 0,74 3,90 8,35
.loc con prealloc 0,24 2,58 8.70
dictar 0,012 0,046 0,084

Entonces uso la suma a través del diccionario para mí.


Código:

import pandas as pd
import numpy as np
import time

del df1, df2, df3, df4
numOfRows = 1000
# append
startTime = time.perf_counter()
df1 = pd.DataFrame(np.random.randint(100, size=(5,5)), columns=['A', 'B', 'C', 'D', 'E'])
for i in range( 1,numOfRows-4):
    df1 = df1.append( dict( (a,np.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)

# .loc w/o prealloc
startTime = time.perf_counter()
df2 = pd.DataFrame(np.random.randint(100, size=(5,5)), columns=['A', 'B', 'C', 'D', 'E'])
for i in range( 1,numOfRows):
    df2.loc[i]  = np.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)

# .loc with prealloc
df3 = pd.DataFrame(index=np.arange(0, numOfRows), columns=['A', 'B', 'C', 'D', 'E'] )
startTime = time.perf_counter()
for i in range( 1,numOfRows):
    df3.loc[i]  = np.random.randint(100, size=(1,5))[0]
print('Elapsed time: {:6.3f} seconds for {:d} rows'.format(time.perf_counter() - startTime, numOfRows))
print(df3.shape)

# dict
startTime = time.perf_counter()
row_list = []
for i in range (0,5):
    row_list.append(dict( (a,np.random.randint(100)) for a in ['A','B','C','D','E']))
for i in range( 1,numOfRows-4):
    dict1 = dict( (a,np.random.randint(100)) for a in ['A','B','C','D','E'])
    row_list.append(dict1)

df4 = pd.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(df4.shape)

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

13
  • 4
    El uso de df2.index.max()for .locaumenta innecesariamente la complejidad computacional. Simple df2.loc[i] = ...serviría. Para mí, redujo el tiempo de 10 segundos a 8,64 segundoskrassowski 23/01/19 a las 20:44
  • Elimine mi nombre de la lista, ya que no está siguiendo mi enfoque en su prueba: no está preasignando la memoria proporcionando un índice de tamaño adecuado. FooBar 29/07/19 a las 18:27
  • @FooBar ¡Hola! Me alegro que ya que el autor vio mi respuesta :) tienes razón, me perdí este punto importante. ¡Prefiero agregar una fila más para mi tabla de resultados ya que su enfoque muestra el resultado diferente! Mikhail_Sam 30/07/19 a las 8:17
  • 1
    @Mikhail_Sam Para el último enfoque, dict, ¿cuál es la razón detrás del uso de dos bucles for i in range (0,5):y for i in range( 1,numOfRows-4):? flow2k 29/09/19 a las 9:03
  • 1
    Solo quería lanzar otro comentario sobre por qué Dict to Pandas DataFrame es una mejor manera. En mi experimentación con un conjunto de datos que tiene múltiples tipos de datos diferentes en la tabla, el uso de los métodos de adición de Pandas destruye la escritura, mientras que el uso de un Dict, y solo creando el DataFrame a partir de él UNA VEZ, parece mantener intactos los tipos de datos originales. trumpetlicks 4 dic 2019 a las 14:23
172

¡NUNCA haga crecer un DataFrame!

Sí, la gente ya ha explicado que NUNCA debe hacer crecer un DataFrame, y que debe agregar sus datos a una lista y convertirlos en un DataFrame una vez al final. ¿Pero entiendes por qué?

Aquí están las razones más importantes, tomadas de mi publicación aquí .

  1. Siempre es más barato / rápido agregar a una lista y crear un DataFrame de una sola vez.
  2. Las listas ocupan menos memoria y son una estructura de datos mucho más liviana para trabajar, agregar y eliminar.
  3. dtypesse infieren automáticamente para sus datos. Por otro lado, la creación de un marco vacío de NaNs hará automáticamente object, lo cual es malo.
  4. Se crea un índice automáticamente para usted, en lugar de que tenga que ocuparse de asignar el índice correcto a la fila que está agregando.

This is The Right Way ™ para acumular sus datos

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

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

Estas opciones son horribles

  1. appendo concatdentro de un bucle

    appendy concatno son intrínsecamente malos de forma aislada . El problema comienza cuando los llama iterativamente dentro de un bucle; esto da como resultado un uso de memoria cuadrático.

    # Creates empty DataFrame and appends
    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)  
        # This is equally bad:
        # df = pd.concat(
        #       [df, pd.Series({'A': i, 'B': b, 'C': c})], 
        #       ignore_index=True)
    
  2. Marco de datos vacío de NaN

    Nunca cree un DataFrame de NaN ya que las columnas se inicializan con object(dtype lento, no vectorizable).

    # Creates DataFrame of NaNs and overwrites values.
    df = pd.DataFrame(columns=['A', 'B', 'C'], index=range(5))
    for a, b, c in some_function_that_yields_data():
        df.loc[len(df)] = [a, b, c]
    

La prueba está en el pudín

Medir el tiempo de estos métodos es la forma más rápida de ver cuánto se diferencian en términos de memoria y utilidad.

ingrese la descripción de la imagen aquí

Código de evaluación comparativa para referencia.


Son publicaciones como esta las que me recuerdan por qué soy parte de esta comunidad. Las personas comprenden la importancia de enseñar a las personas a obtener la respuesta correcta con el código correcto , no la respuesta correcta con el código incorrecto . Ahora puede argumentar que no es un problema para usar loco appendsi solo está agregando una sola fila a su DataFrame. Sin embargo, las personas a menudo miran esta pregunta para agregar más de una fila ; a menudo, el requisito es agregar iterativamente una fila dentro de un ciclo utilizando datos que provienen de una función (consulte la pregunta relacionada ). En ese caso, es importante comprender que el crecimiento iterativo de un DataFrame no es una buena idea.

9
  • 5
    Lo suficientemente justo. ¿Existe alguna solución en caso de que necesite (o desee) un marco de datos, pero todas sus muestras realmente vienen una tras otra? (Por lo general, aprendizaje en línea o aprendizaje activo)user1657853 8 de septiembre de 2020 a las 15:52
  • Esto no tiene en cuenta el caso en el que se necesita el marco de datos después de cada append (). En ese caso, el marco de datos se copia de todos modos, por lo que el método df.loc es más rápidoDev Aggarwal 17 de septiembre de 2020 a las 10:45
  • @DevAggarwal incorrecto, loc también crea una copia cada vez. Consulte los tiempos del gráfico en mi respuesta. Append y loc_append son igualmente malos. También he compartido mi código y proceso para que pueda convencerse a sí mismo. cs95 17/09/20 a las 16:36
  • Las disculpas deberían haber sido más claras. Por favor cree el marco de datos de la lista intermedia dentro del bucle for, aquí - gist.github.com/Coldsp33d/…Dev Aggarwal 17/09/20 a las 17:10
  • 1
    buena respuesta @ cs95! adir abargil 5 de enero a las 12:44
123

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, según los comentarios, con un tamaño de 6000, la diferencia de velocidad se vuelve aún mayor:

Increasing the size of the array (12) and the number of rows (500) makes the speed difference more striking: 313ms vs 2.29s

2
  • 4
    Gran respuesta. Esta debería ser la norma para que el espacio de fila no tenga que asignarse de forma incremental. ely 9/10/2014 a las 18:32
  • 9
    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: 313ms vs 2.29sTickon 2/04/2015 a las 10:55
91
mycolumns = ['A', 'B']
df = pd.DataFrame(columns=mycolumns)
rows = [[1,2],[3,4],[5,6]]
for row in rows:
    df.loc[len(df)] = row
2
  • 3
    ¡Esta! He estado buscando durante bastante tiempo, ¡y esta es la primera publicación que realmente muestra cómo asignar valores particulares a una fila! Pregunta adicional: ¿Cuál es la sintaxis de los pares columna-nombre / valor? Supongo que debe ser algo que usa un dictado, pero parece que no puedo hacerlo bien. jhin 9 de marzo de 2016 a las 0:00
  • 7
    esto no es eficiente ya que en realidad copia todo el DataFrame cuando lo extiende. waterproof 25/07/19 a las 16:42
78

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

>>> 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
4
  • 46
    También puede mencionar que f.append(<stuff>)crea un nuevo objeto, en lugar de simplemente agregarlo al objeto actual en su lugar, por lo que si está tratando de agregar un marco de datos en un script, debe decirf = f.append(<stuff>)Blairg23 28 de mayo de 2016 a las 3:57
  • 2
    ¿Hay alguna manera de hacer esto en su lugar? lol 8 de noviembre de 2016 a las 3:48
  • @lol no. consulte github.com/pandas-dev/pandas/issues/2801 : las matrices subyacentes no se pueden extender, por lo que deben copiarse. waterproof 25/07/19 a las 16:42
  • 1
    Prefiero este método porque es muy similar a SQL (no depende semánticamente de índices) y lo uso siempre que sea posible. Gene M 31 jul.20 a las 21:45
75

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

Agregue filas a través loc/ixde datos de índice de clave no existentes . Por ejemplo:

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]:
   A  B
0  0  1
1  2  3
2  4  5

In [3]: dfi.loc[:,'C'] = dfi.loc[:,'A']

In [4]: dfi
Out[4]:
   A  B  C
0  0  1  0
1  2  3  2
2  4  5  4
In [5]: dfi.loc[3] = 5

In [6]: dfi
Out[6]:
   A  B  C
0  0  1  0
1  2  3  2
2  4  5  4
3  5  5  5
3
  • 1
    Los usuarios solicitaron implementar (agregar una nueva fila). Aquí vemos cómo agregar una fila en un índice definido o agregar una columna. Guilherme Felipe Reis 21 feb 2019 a las 15:38
  • 1
    cualquier punto de referencia sobre cómo funciona esto en comparación con el método dictPirateApp 6 mar 19 a las 17:15
  • esto no es eficiente ya que en realidad copia todo el DataFrame. waterproof 25/07/19 a las 16:41
47

Por el bien de una forma pitónica:

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
0
33

También puede crear una lista de listas y convertirla en un marco de datos:

import pandas as pd

columns = ['i','double','square']
rows = []

for i in range(6):
    row = [i, i*2, i*i]
    rows.append(row)

df = pd.DataFrame(rows, columns=columns)

donación

    i   double  square
0   0   0   0
1   1   2   1
2   2   4   4
3   3   6   9
4   4   8   16
5   5   10  25
16

Descubrí una manera simple y agradable:

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

Tenga en cuenta la advertencia con el rendimiento como se indica en los comentarios.

1
  • 2
    Tenga en cuenta que esto copiará todo el DataFrame debajo del capó. Las matrices subyacentes no se pueden extender, por lo que deben copiarse. waterproof 25/07/19 a las 16:43
14

Esta no es una respuesta a la pregunta OP, sino un ejemplo de juguete para ilustrar la respuesta de ShikharDua que encontré 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 diferentes columnas y luego realizar las estadísticas a continuación para más de una columna de destino. Por lo tanto, tener un método confiable para construir el marco de datos una fila a la vez fue una gran comodidad. ¡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)
10

Puede usar un objeto generador para crear un marco de datos, que será más eficiente en memoria que la lista.

num = 10

# Generator function to generate generator object
def numgen_func(num):
    for i in range(num):
        yield ('name_{}'.format(i), (i*i), (i*i*i))

# Generator expression to generate generator object (Only once data get populated, can not be re used)
numgen_expression = (('name_{}'.format(i), (i*i), (i*i*i)) for i in range(num) )

df = pd.DataFrame(data=numgen_func(num), columns=('lib', 'qty1', 'qty2'))

Para agregar sin procesar a DataFrame existente, puede usar el método de adición.

df = df.append([{ 'lib': "name_20", 'qty1': 20, 'qty2': 400  }])
8

Cree un nuevo registro (marco de datos) y agréguelo a old_data_frame .

Pase una lista de valores y los nombres de las columnas correspondientes para crear un new_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])
7

Esta es la forma de agregar / agregar una fila en un Pandas DataFrame:

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 un Pandas DataFrame vacío o poblado.

1
  • 1
    esto se suma con índice en orden descendenteParthiban Rajendran 13 oct 2018 a las 17:33
7

En lugar de una lista de diccionarios como en la respuesta de ShikharDua , también podemos representar nuestra tabla como un diccionario de listas , donde cada lista almacena una columna en orden de filas, dado que conocemos nuestras columnas de antemano. Al final, construimos nuestro DataFrame una vez.

Para c columnas y n filas, esto usa un diccionario y listas c , versus una lista y n diccionarios. El método de lista de diccionarios hace que cada diccionario almacene todas las claves y requiere la creación de un nuevo diccionario para cada fila. Aquí solo agregamos a listas, que es un tiempo constante y teóricamente muy rápido.

# Current data
data = {"Animal":["cow", "horse"], "Color":["blue", "red"]}

# Adding a new row (be careful to ensure every column gets another value)
data["Animal"].append("mouse")
data["Color"].append("black")

# At the end, construct our DataFrame
df = pd.DataFrame(data)
#   Animal  Color
# 0    cow   blue
# 1  horse    red
# 2  mouse  black
5

Si siempre desea agregar una nueva fila al final, use esto:

df.loc[len(df)] = ['name5', 9, 0]
4

Si desea agregar una fila al final, agréguela como una lista:

valuestoappend = [va1, val2, val3]
res = res.append(pd.Series(valuestoappend, index = ['lib', 'qty1', 'qty2']), ignore_index = True)
3

Otra forma de hacerlo (probablemente no muy eficiente):

# 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
3

Todo lo que necesitas es loc[df.shape[0]]oloc[len(df)]


# Assuming your df has 4 columns (str, int, str, bool)
df.loc[df.shape[0]] = ['col1Value', 100, 'col3Value', False] 

o

df.loc[len(df)] = ['col1Value', 100, 'col3Value', False] 
2
initial_data = {'lib': np.array([1,2,3,4]), 'qty1': [1,2,3,4], 'qty2': [1,2,3,4]}

df = pd.DataFrame(initial_data)

df

lib    qty1    qty2
0    1    1    1
1    2    2    2
2    3    3    3
3    4    4    4

val_1 = [10]
val_2 = [14]
val_3 = [20]

df.append(pd.DataFrame({'lib': val_1, 'qty1': val_2, 'qty2': val_3}))

lib    qty1    qty2
0    1    1    1
1    2    2    2
2    3    3    3
3    4    4    4
0    10    14    20

Puede usar un bucle for para iterar a través de los valores o puede agregar matrices de valores.

val_1 = [10, 11, 12, 13]
val_2 = [14, 15, 16, 17]
val_3 = [20, 21, 22, 43]

df.append(pd.DataFrame({'lib': val_1, 'qty1': val_2, 'qty2': val_3}))

lib    qty1    qty2
0    1    1    1
1    2    2    2
2    3    3    3
3    4    4    4
0    10    14    20
1    11    15    21
2    12    16    22
3    13    17    43
1
  • Una explicación de la primera parte estaría en orden. ¿Y por qué no hay un bucle "for" en el código de ejemplo cuando se habla de él? ¿Puedes dejarlo más claro? Responda editando su respuesta , no aquí en los comentarios ( sin "Editar:", "Actualizar:" o similar; la respuesta debería aparecer como si estuviera escrita hoy). Peter Mortensen 14 de julio a las 10:14
1

Hazlo simple. Tomando una lista como entrada que se agregará como una fila en el marco de datos:

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)
0
0

Si tiene un marco de datos dfy desea agregar una lista new_list como una nueva fila df, simplemente puede hacer:

df.loc[len(df)] = new_list

Si desea agregar un nuevo marco de new_df datos debajo del marco de datos df, puede usar:

df.append(new_df)
0

A menudo vemos la construcción df.loc[subscript] = …para asignar a una fila de DataFrame. Mikhail_Sam publicó puntos de referencia que contienen, entre otros, esta construcción, así como el método que usa dict y crea DataFrame al final . Encontró que este último era el más rápido con diferencia.

Pero si reemplazamos el df3.loc[i] = …(con DataFrame preasignado) en su código con df3.values[i] = …, el resultado cambia significativamente, ya que ese método funciona de manera similar al que usa dict. Por tanto, deberíamos tener más en cuenta el uso de df.values[subscript] = …. Sin embargo, tenga en cuenta que .valuestoma un subíndice de base cero, que puede ser diferente del DataFrame.index.

1
0

pandas.DataFrame.append

DataFrame.append (self, other, ignore_index = False, verify_integrity = False, sort = False) → 'DataFrame'

Código

df = pd.DataFrame([[1, 2], [3, 4]], columns=list('AB'))
df2 = pd.DataFrame([[5, 6], [7, 8]], columns=list('AB'))
df.append(df2)

Con ignore_index establecido en True:

df.append(df2, ignore_index=True)
1
  • No está claro por qué las dos primeras líneas no son un código literal. La brevedad es buena, pero ¿puede desarrollar su respuesta , por ejemplo, agregando algún texto de apoyo? Pero sin "Editar:", "Actualizar:" o similar, la respuesta debería aparecer como si estuviera escrita hoy. Peter Mortensen 14 de julio a las 10:05
0

Puede concatenar dos DataFrames para esto. Básicamente, encontré este problema para agregar una nueva fila a un DataFrame existente con un índice de caracteres (no numérico).

Entonces, ingreso los datos para una nueva fila en un duct () y los indexo en una lista.

new_dict = {put input for new row here}
new_list = [put your index here]

new_df = pd.DataFrame(data=new_dict, index=new_list)

df = pd.concat([existing_df, new_df])
0

Si todos los datos en su marco de datos tienen el mismo tipo d, puede usar una matriz NumPy. Puede escribir filas directamente en la matriz predefinida y convertirla en un marco de datos al final. Parece ser incluso más rápido que convertir una lista de dictados.

import pandas as pd
import numpy as np
from string import ascii_uppercase

startTime = time.perf_counter()
numcols, numrows = 5, 10000
npdf = np.ones((numrows, numcols))
for row in range(numrows):
    npdf[row, 0:] = np.random.randint(0, 100, (1, numcols))
df5 = pd.DataFrame(npdf, columns=list(ascii_uppercase[:numcols]))
print('Elapsed time: {:6.3f} seconds for {:d} rows'.format(time.perf_counter() - startTime, numOfRows))
print(df5.shape)
1
  • Re "Parece ser aún más rápido" : ¿Puedes cuantificar eso ( editando (cambiando) tu respuesta )? ¿De qué orden estamos hablando? 10% más rápido? 100% más rápido? 10 veces más rápido? 1.000.000 de veces más rápido? ¿A qué escala (podría ser cuadrática / exponencial)? Peter Mortensen 14 de julio a las 10:25
0

Este fragmento de código utiliza una lista de diccionarios para actualizar el marco de datos. Se suma a las respuestas de ShikharDua y Mikhail_Sam .

import pandas as pd
colour = ["red", "big", "tasty"]
fruits = ["apple", "banana", "cherry"]
dict1={}
feat_list=[]
for x in colour:
    for y in fruits:
#         print(x, y)
        dict1 = dict([('x',x),('y',y)])
#         print(f'dict 1 {dict1}')
        feat_list.append(dict1)
#         print(f'feat_list {feat_list}')
feat_df=pd.DataFrame(feat_list)
feat_df.to_csv('feat1.csv')
-1

Antes de agregar una fila, tenemos que convertir el marco de datos en un diccionario. Allí puede ver las claves como columnas en el marco de datos y los valores de las columnas se almacenan nuevamente en el diccionario, pero allí la clave para cada columna es el número de índice en el marco de datos.

Esa idea me hace escribir el siguiente código.

df2 = df.to_dict()
values = ["s_101", "hyderabad", 10, 20, 16, 13, 15, 12, 12, 13, 25, 26, 25, 27, "good", "bad"] # This is the total row that we are going to add
i = 0
for x in df.columns:   # Here df.columns gives us the main dictionary key
    df2[x][101] = values[i]   # Here the 101 is our index number. It is also the key of the sub dictionary
    i += 1