Panda Python: riempie un frame di dati riga per riga


133

Il semplice compito di aggiungere una riga a un pandas.DataFrameoggetto sembra essere difficile da realizzare. Ci sono 3 domande stackoverflow relative a questo, nessuna delle quali fornisce una risposta funzionante.

Ecco cosa sto cercando di fare. Ho un DataFrame di cui conosco già la forma, nonché i nomi delle righe e delle colonne.

>>> df = pandas.DataFrame(columns=['a','b','c','d'], index=['x','y','z'])
>>> df
     a    b    c    d
x  NaN  NaN  NaN  NaN
y  NaN  NaN  NaN  NaN
z  NaN  NaN  NaN  NaN

Ora, ho una funzione per calcolare iterativamente i valori delle righe. Come posso compilare una delle righe con un dizionario o un pandas.Series? Ecco vari tentativi falliti:

>>> y = {'a':1, 'b':5, 'c':2, 'd':3} 
>>> df['y'] = y
AssertionError: Length of values does not match length of index

Apparentemente ha provato ad aggiungere una colonna anziché una riga.

>>> y = {'a':1, 'b':5, 'c':2, 'd':3} 
>>> df.join(y)
AttributeError: 'builtin_function_or_method' object has no attribute 'is_unique'

Messaggio di errore molto poco informativo.

>>> y = {'a':1, 'b':5, 'c':2, 'd':3} 
>>> df.set_value(index='y', value=y)
TypeError: set_value() takes exactly 4 arguments (3 given)

Apparentemente è solo per l'impostazione di singoli valori nel frame di dati.

>>> y = {'a':1, 'b':5, 'c':2, 'd':3} 
>>> df.append(y)
Exception: Can only append a Series if ignore_index=True

Bene, non voglio ignorare l'indice, altrimenti ecco il risultato:

>>> df.append(y, ignore_index=True)
     a    b    c    d
0  NaN  NaN  NaN  NaN
1  NaN  NaN  NaN  NaN
2  NaN  NaN  NaN  NaN
3    1    5    2    3

Allineava i nomi delle colonne con i valori, ma perse le etichette delle righe.

>>> y = {'a':1, 'b':5, 'c':2, 'd':3} 
>>> df.ix['y'] = y
>>> df
                                  a                                 b  \
x                               NaN                               NaN
y  {'a': 1, 'c': 2, 'b': 5, 'd': 3}  {'a': 1, 'c': 2, 'b': 5, 'd': 3}
z                               NaN                               NaN

                                  c                                 d
x                               NaN                               NaN
y  {'a': 1, 'c': 2, 'b': 5, 'd': 3}  {'a': 1, 'c': 2, 'b': 5, 'd': 3}
z                               NaN                               NaN

Anche quello fallì miseramente.

Quindi come lo fai?

Risposte:


92

df['y'] imposterà una colonna

poiché vuoi impostare una riga, usa .loc

Nota che .ixqui è equivalente, il tuo non è riuscito perché hai tentato di assegnare un dizionario a ciascun elemento della riga yprobabilmente non quello che desideri; la conversione in una serie indica ai panda che si desidera allineare l'input (ad esempio, non è necessario specificare tutti gli elementi)

In [7]: df = pandas.DataFrame(columns=['a','b','c','d'], index=['x','y','z'])

In [8]: df.loc['y'] = pandas.Series({'a':1, 'b':5, 'c':2, 'd':3})

In [9]: df
Out[9]: 
     a    b    c    d
x  NaN  NaN  NaN  NaN
y    1    5    2    3
z  NaN  NaN  NaN  NaN

Vedo. Quindi l' locattributo del data frame definisce uno speciale __setitem__che fa la magia suppongo.
xApple,

Puoi costruirlo in un passaggio (cioè con colonne, indice e y)?
Andy Hayden,

5
Quindi, se posso generare una riga alla volta, come potrei costruire il frame di dati in modo ottimale?
xApple

Mi aspettavo qualche variante di df = pd.DataFrame({'y': pd.Series(y)}, columns=['a','b','c','d'], index=['x','y','z'])funzionare?
Andy Hayden,

@xApple è meglio per te per costruire un elenco di dicts (o elenco), quindi passare al costruttore, sarà molto più efficiente
Jeff

71

Il mio approccio è stato, ma non posso garantire che questa sia la soluzione più veloce.

df = pd.DataFrame(columns=["firstname", "lastname"])
df = df.append({
     "firstname": "John",
     "lastname":  "Johny"
      }, ignore_index=True)

4
Questo ha funzionato perfettamente per me e mi piace il fatto che tu abbia esplicitamente appendi dati nel dataframe.
Jonny Brooks,

1
Nota che questa risposta richiede che ogni riga abbia il nome della colonna aggiunto. Lo stesso vale per la risposta accettata.
Pashute,

Questo funziona anche se non si conosce in anticipo il numero di righe.
irene,

34

Questa è una versione più semplice

import pandas as pd
df = pd.DataFrame(columns=('col1', 'col2', 'col3'))
for i in range(5):
   df.loc[i] = ['<some value for first>','<some value for second>','<some value for third>']`

4
voglio solo chiedere, questa CPU e memoria è efficiente?
czxttkl,

1
come faccio a sapere l'ultima riga di df in modo da aggiungere ogni volta l'ultima riga?
pashute,

25

Se le righe di input sono elenchi anziché dizionari, la seguente è una soluzione semplice:

import pandas as pd
list_of_lists = []
list_of_lists.append([1,2,3])
list_of_lists.append([4,5,6])

pd.DataFrame(list_of_lists, columns=['A', 'B', 'C'])
#    A  B  C
# 0  1  2  3
# 1  4  5  6

ma cosa devo fare se ho un indice multiplo? df1 = pd.DataFrame (list_of_lists, colonne ['A', 'B', 'C'], index = ['A', 'B']) non funziona. Forma sbagliata. Così come?
Pashute,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.