Inserisci una riga in pandas dataframe


112

Ho un dataframe:

s1 = pd.Series([5, 6, 7])
s2 = pd.Series([7, 8, 9])

df = pd.DataFrame([list(s1), list(s2)],  columns =  ["A", "B", "C"])

   A  B  C
0  5  6  7
1  7  8  9

[2 rows x 3 columns]

e devo aggiungere una prima riga [2, 3, 4] per ottenere:

   A  B  C
0  2  3  4
1  5  6  7
2  7  8  9

Ho provato append()e concat()funziona ma non riesco a trovare il modo giusto per farlo.

Come aggiungere / inserire serie a dataframe?


6
nota che è meglio usare s1.valuesinvece di list(s1)creare un elenco completamente nuovo usando list(s1).
acushner

7
Non capisco perché tutti amino così tanto i panda quando qualcosa che dovrebbe essere così semplice è un tale rompicoglioni e così lento.
MattCochrane

Risposte:


145

Assegna semplicemente una riga a un particolare indice, usando loc:

 df.loc[-1] = [2, 3, 4]  # adding a row
 df.index = df.index + 1  # shifting index
 df = df.sort_index()  # sorting by index

E ottieni, come desiderato:

    A  B  C
 0  2  3  4
 1  5  6  7
 2  7  8  9

Vedere nella documentazione di Pandas Indicizzazione: impostazione con ingrandimento .


2
Se non si desidera impostare con l'allargamento, ma inserto all'interno del dataframe, dare un'occhiata a stackoverflow.com/questions/15888648/...
FooBar

6
alternativa all'indice mobile: df.sort (). reset_index (drop = True)
Meloun

2
df.sort è deprecato, usa df.sort_index ()
GBGOLC

1
@ Piotr - funziona benissimo, ma cosa succede quando si desidera duplicare una riga dal frame di dati, ad esempio df.loc[-1] = df.iloc[[0]], e inserirla? Il frame viene fornito con una colonna indice aggiunta che fornisce errori ValueError: cannot set a row with mismatched columns (vedi stackoverflow.com/questions/47340571/… )
Growler

5
Penso che df.loc[-1] = [2, 3, 4] # adding a rowsia un po 'fuorviante, in quanto -1non è l'ultima riga / elemento, come lo è per gli array Python.
flow2k

26

Non sono sicuro di come stavi chiamando, concat()ma dovrebbe funzionare fintanto che entrambi gli oggetti sono dello stesso tipo. Forse il problema è che devi lanciare il tuo secondo vettore su un dataframe? Usare il df che hai definito per me funziona:

df2 = pd.DataFrame([[2,3,4]], columns=['A','B','C'])
pd.concat([df2, df])

Migliore risposta ^ :)
Cam.Davidson.Pilon

23

Un modo per ottenere questo risultato è

>>> pd.DataFrame(np.array([[2, 3, 4]]), columns=['A', 'B', 'C']).append(df, ignore_index=True)
Out[330]: 
   A  B  C
0  2  3  4
1  5  6  7
2  7  8  9

In generale, è più semplice aggiungere dataframe, non serie. Nel tuo caso, dato che vuoi che la nuova riga sia "in alto" (con ID iniziale) e non c'è alcuna funzione pd.prepend(), creo prima il nuovo dataframe e poi aggiungo quello vecchio.

ignore_indexignorerà il vecchio indice in corso nel tuo dataframe e assicurerà che la prima riga inizi effettivamente con index 1invece di riavviare con index 0.

Disclaimer tipico: Cetero censeo ... l'aggiunta di righe è un'operazione abbastanza inefficiente. Se ti interessano le prestazioni e puoi in qualche modo assicurarti di creare prima un dataframe con l'indice corretto (più lungo) e poi inserire semplicemente la riga aggiuntiva nel dataframe, dovresti assolutamente farlo. Vedere:

>>> index = np.array([0, 1, 2])
>>> df2 = pd.DataFrame(columns=['A', 'B', 'C'], index=index)
>>> df2.loc[0:1] = [list(s1), list(s2)]
>>> df2
Out[336]: 
     A    B    C
0    5    6    7
1    7    8    9
2  NaN  NaN  NaN
>>> df2 = pd.DataFrame(columns=['A', 'B', 'C'], index=index)
>>> df2.loc[1:] = [list(s1), list(s2)]

Finora, abbiamo quello che avevi come df:

>>> df2
Out[339]: 
     A    B    C
0  NaN  NaN  NaN
1    5    6    7
2    7    8    9

Ma ora puoi inserire facilmente la riga come segue. Poiché lo spazio è stato preallocato, questo è più efficiente.

>>> df2.loc[0] = np.array([2, 3, 4])
>>> df2
Out[341]: 
   A  B  C
0  2  3  4
1  5  6  7
2  7  8  9

Questa è una bella soluzione di lavoro, stavo cercando di inserire serie nel dataframe. È abbastanza buono per me al momento.
Meloun

L'ultima opzione mi piace di più. Questo corrisponde veramente a ciò che voglio veramente fare. Grazie @FooBar!
Jade Cacho

13

Ho messo insieme una breve funzione che consente un po 'più di flessibilità durante l'inserimento di una riga:

def insert_row(idx, df, df_insert):
    dfA = df.iloc[:idx, ]
    dfB = df.iloc[idx:, ]

    df = dfA.append(df_insert).append(dfB).reset_index(drop = True)

    return df

che potrebbe essere ulteriormente abbreviato in:

def insert_row(idx, df, df_insert):
    return df.iloc[:idx, ].append(df_insert).append(df.iloc[idx:, ]).reset_index(drop = True)

Quindi potresti usare qualcosa come:

df = insert_row(2, df, df_new)

dov'è 2la posizione dell'indice in dfcui si desidera inserire df_new.


7

Possiamo usare numpy.insert. Questo ha il vantaggio della flessibilità. Devi solo specificare l'indice in cui vuoi inserire.

s1 = pd.Series([5, 6, 7])
s2 = pd.Series([7, 8, 9])

df = pd.DataFrame([list(s1), list(s2)],  columns =  ["A", "B", "C"])

pd.DataFrame(np.insert(df.values, 0, values=[2, 3, 4], axis=0))

    0   1   2
0   2   3   4
1   5   6   7
2   7   8   9

Per np.insert(df.values, 0, values=[2, 3, 4], axis=0), 0 dice alla funzione il posto / indice in cui vuoi inserire i nuovi valori.


6

questo potrebbe sembrare eccessivamente semplice ma è incredibile che una semplice funzione di inserimento di una nuova riga non sia incorporata. Ho letto molto sull'aggiunta di un nuovo df all'originale, ma mi chiedo se questo sarebbe più veloce.

df.loc[0] = [row1data, blah...]
i = len(df) + 1
df.loc[i] = [row2data, blah...]

Intendevi "aggiungere un nuovo df" o semplicemente "aggiungere una nuova riga", come mostra il tuo codice?
smci

scusa la mia frase non era chiara. Ho letto soluzioni di altre persone che concatenano / aggiungono un nuovo dataframe con una sola riga. ma nella mia soluzione è solo una singola riga nel dataframe esistente, non è necessario creare un dataframe aggiuntivo
Aaron Melgar

6

Di seguito sarebbe il modo migliore per inserire una riga nel dataframe panda senza ordinare e reimpostare un indice:

import pandas as pd

df = pd.DataFrame(columns=['a','b','c'])

def insert(df, row):
    insert_loc = df.index.max()

    if pd.isna(insert_loc):
        df.loc[0] = row
    else:
        df.loc[insert_loc + 1] = row

insert(df,[2,3,4])
insert(df,[8,9,0])
print(df)

perché dici che questo è il modo migliore?
Yuca

allora sarebbe bello fornire prove a sostegno di tale affermazione, hai cronometrato?
Yuca

1
puoi usare pd.isna per evitare di importare numpy
kato2

2

È piuttosto semplice aggiungere una riga in un panda DataFrame:

  1. Crea un normale dizionario Python con gli stessi nomi di colonne del tuo Dataframe;

  2. Usa il pandas.append()metodo e passa il nome del tuo dizionario, dove .append()è un metodo sulle istanze di DataFrame;

  3. Aggiungi ignore_index=Truesubito dopo il nome del dizionario.


Questa è probabilmente l'opzione più preferibile (intorno al 2020).
David Golembiowski,

1

concat()sembra essere un po 'più veloce dell'inserimento e della reindicizzazione dell'ultima riga. Nel caso qualcuno si interrogasse sulla velocità di due approcci principali:

In [x]: %%timeit
     ...: df = pd.DataFrame(columns=['a','b'])
     ...: for i in range(10000):
     ...:     df.loc[-1] = [1,2]
     ...:     df.index = df.index + 1
     ...:     df = df.sort_index()

17,1 s ± 705 ms per loop (media ± dev. Std. Di 7 analisi, 1 loop ciascuna)

In [y]: %%timeit
     ...: df = pd.DataFrame(columns=['a', 'b'])
     ...: for i in range(10000):
     ...:     df = pd.concat([pd.DataFrame([[1,2]], columns=df.columns), df])

6,53 s ± 127 ms per loop (media ± dev. Std. Di 7 analisi, 1 loop ciascuna)


0

Puoi semplicemente aggiungere la riga alla fine del DataFrame e quindi regolare l'indice.

Per esempio:

df = df.append(pd.DataFrame([[2,3,4]],columns=df.columns),ignore_index=True)
df.index = (df.index + 1) % len(df)
df = df.sort_index()

Oppure usa concatcome:

df = pd.concat([pd.DataFrame([[1,2,3,4,5,6]],columns=df.columns),df],ignore_index=True)

-1

Il modo più semplice per aggiungere una riga in un frame di dati Panda è:

DataFrame.loc[ location of insertion ]= list( )

Esempio :

DF.loc[ 9 ] = [ ´Pepe , 33, ´Japan ]

NB: la lunghezza della tua lista deve corrispondere a quella del data frame.


ha fatto il trucco per me!
Sam Shaw
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.