Konwertuj nagłówek wiersza na kolumnę dla Pandas DataFrame,

111

Dane, z którymi muszę pracować, są trochę niechlujne ... Zawiera nazwy nagłówków w swoich danych. Jak mogę wybrać wiersz z istniejącej ramki danych pandy i ustawić go (zmienić jego nazwę na) jako nagłówek kolumny?

Chcę zrobić coś takiego:

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

df.columns = header
EK
źródło

Odpowiedzi:

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

Ustaw etykiety kolumn tak, aby były równe wartościom w drugim wierszu (lokalizacja indeksu 1):

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

Jeśli indeks ma unikalne etykiety, możesz usunąć drugi wiersz za pomocą:

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

Jeśli indeks nie jest unikalny, możesz użyć:

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

Użycie df.drop(df.index[1])powoduje usunięcie wszystkich wierszy z tą samą etykietą co drugi wiersz. Ponieważ nieunikalne indeksy mogą prowadzić do takich problemów (lub potencjalnych błędów), często lepiej jest zadbać o to, aby indeks był unikalny (nawet jeśli Pandy tego nie wymagają).

unutbu
źródło
Dziękuję bardzo za szybką odpowiedź! Jak wybrać wiersz według wartości zamiast lokalizacji indeksu, aby był nagłówkiem? Więc na przykład coś w stylu .. df.columns = df [df [0] == 'foo']
EK
Problem polega na tym, że może istnieć więcej niż jeden wiersz zawierający tę wartość "foo". Jednym ze sposobów obejścia tego problemu jest jednoznacznie wybrać pierwszy taki wiersz: df.columns = df.iloc[np.where(df[0] == 'foo')[0][0]].
unutbu
Ach, rozumiem, dlaczego to zrobiłeś. W moim przypadku wiem, że istnieje tylko jeden wiersz, który ma wartość „foo”. Więc to jest w porządku. Właśnie zrobiłem w ten sposób, myślę, że jest taki sam, jak ten, który mi dałeś powyżej. idx_loc = df [df [0] == 'foo']. index.tolist () [0] df.columns = df.iloc [idx_loc]
EK
63

To działa (pandas v'0.19.2 '):

df.rename(columns=df.iloc[0])
Zachary Wilson
źródło
22
Możesz usunąć wiersz „nagłówka” dodając.drop(df.index[0])
ostrokach
Podoba mi się to bardziej niż faktycznie zaakceptowana odpowiedź. Uwielbiam krótkie rozwiązania online.
Javier
13

Byłoby łatwiej odtworzyć ramkę danych. Spowoduje to również zinterpretowanie typów kolumn od podstaw.

headers = df.iloc[0]
new_df  = pd.DataFrame(df.values[1:], columns=headers)
shahar_m
źródło
4

Możesz określić indeks wiersza w konstruktorach read_csv lub read_html za pomocą headerparametru, który reprezentuje Row number(s) to use as the column names, and the start of the data. Ma to tę zaletę, że automatycznie usuwa wszystkie poprzednie wiersze, które przypuszczalnie są śmieciami.

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
ccpizza
źródło