Converti intestazione riga in colonna per Pandas DataFrame,


111

I dati con cui devo lavorare sono un po 'disordinati .. Ha nomi di intestazione all'interno dei suoi dati. Come posso scegliere una riga da un dataframe panda esistente e renderla (rinominarla) un'intestazione di colonna?

Voglio fare qualcosa come:

header = df[df['old_header_name1'] == 'new_header_name1']

df.columns = header

Risposte:


196
In [21]: df = pd.DataFrame([(1,2,3), ('foo','bar','baz'), (4,5,6)])

In [22]: df
Out[22]: 
     0    1    2
0    1    2    3
1  foo  bar  baz
2    4    5    6

Imposta le etichette delle colonne in modo che siano uguali ai valori nella seconda riga (posizione indice 1):

In [23]: df.columns = df.iloc[1]

Se l'indice ha etichette univoche, puoi eliminare la seconda riga utilizzando:

In [24]: df.drop(df.index[1])
Out[24]: 
1 foo bar baz
0   1   2   3
2   4   5   6

Se l'indice non è univoco, puoi utilizzare:

In [133]: df.iloc[pd.RangeIndex(len(df)).drop(1)]
Out[133]: 
1 foo bar baz
0   1   2   3
2   4   5   6

L'utilizzo df.drop(df.index[1])rimuove tutte le righe con la stessa etichetta della seconda riga. Poiché gli indici non univoci possono portare a blocchi (o potenziali bug) come questo, spesso è meglio fare attenzione che l'indice sia unico (anche se Pandas non lo richiede).


Grazie mille per la tua rapida risposta! Come posso scegliere una riga in base al valore al posto della posizione dell'indice per renderla intestazione? Quindi, per il tuo esempio, qualcosa come .. df.columns = df [df [0] == 'foo']
EK

Il problema è che potrebbe esserci più di una riga con il valore "foo". Un modo per aggirare il problema è quello di scegliere in modo esplicito la prima di queste righe: df.columns = df.iloc[np.where(df[0] == 'foo')[0][0]].
unutbu

Ah capisco perché l'hai fatto in quel modo. Nel mio caso, so che c'è solo una riga che ha il valore "foo". Quindi va bene. Ho appena fatto in questo modo, immagino sia lo stesso di quello che mi hai dato sopra. idx_loc = df [df [0] == 'foo']. index.tolist () [0] df.columns = df.iloc [idx_loc]
EK

63

Funziona (panda v'0.19.2 '):

df.rename(columns=df.iloc[0])

22
Puoi rimuovere la riga "intestazione" aggiungendo.drop(df.index[0])
ostrokach

Mi piace di più rispetto alla risposta effettivamente accettata. Adoro le soluzioni brevi in ​​linea.
Javier

13

Sarebbe più facile ricreare il data frame. Questo interpreterebbe anche i tipi di colonne da zero.

headers = df.iloc[0]
new_df  = pd.DataFrame(df.values[1:], columns=headers)

4

È possibile specificare l'indice di riga nei costruttori read_csv o read_html tramite il headerparametro che rappresenta Row number(s) to use as the column names, and the start of the data. Questo ha il vantaggio di eliminare automaticamente tutte le righe precedenti che presumibilmente sono spazzatura.

import pandas as pd
from io import StringIO

In[1]
    csv = '''junk1, junk2, junk3, junk4, junk5
    junk1, junk2, junk3, junk4, junk5
    pears, apples, lemons, plums, other
    40, 50, 61, 72, 85
    '''

    df = pd.read_csv(StringIO(csv), header=2)
    print(df)

Out[1]
       pears   apples   lemons   plums   other
    0     40       50       61      72      85
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.