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.