Konversi baris ke header kolom untuk Pandas DataFrame,

111

Data yang harus saya kerjakan agak berantakan .. Ini memiliki nama header di dalam datanya. Bagaimana cara memilih baris dari kerangka data pandas yang ada dan menjadikannya (mengganti namanya menjadi) tajuk kolom?

Saya ingin melakukan sesuatu seperti:

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

df.columns = header
EK
sumber

Jawaban:

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

Atur label kolom agar sama dengan nilai di baris ke-2 (lokasi indeks 1):

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

Jika indeks memiliki label unik, Anda dapat melepaskan baris ke-2 menggunakan:

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

Jika indeks tidak unik, Anda dapat menggunakan:

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

Menggunakan df.drop(df.index[1])menghapus semua baris dengan label yang sama seperti baris kedua. Karena indeks non-unik dapat menyebabkan batu sandungan (atau potensi bug) seperti ini, lebih baik berhati-hati agar indeks tersebut unik (meskipun Pandas tidak memerlukannya).

unutbu
sumber
Terimakasih banyak untuk respon cepat Anda! Bagaimana saya bisa memilih baris demi nilai sebagai ganti lokasi indeks untuk menjadikannya tajuk? Jadi untuk contoh Anda sesuatu seperti .. df.columns = df [df [0] == 'foo']
EK
Masalahnya adalah mungkin ada lebih dari satu baris yang memiliki nilai "foo". Salah satu cara mengatasi masalah yang secara eksplisit memilih baris pertama seperti: df.columns = df.iloc[np.where(df[0] == 'foo')[0][0]].
unutbu
Ah, saya mengerti mengapa Anda melakukan itu. Untuk kasus saya, saya tahu hanya ada satu baris yang memiliki nilai "foo". Jadi tidak apa-apa. Saya baru saja melakukan cara ini, saya kira itu sama dengan yang Anda berikan kepada saya di atas. idx_loc = df [df [0] == 'foo']. index.tolist () [0] df.columns = df.iloc [idx_loc]
EK
63

Ini bekerja (pandas v'0.19.2 '):

df.rename(columns=df.iloc[0])
Zachary Wilson
sumber
22
Anda dapat menghapus baris "header" dengan menambahkan.drop(df.index[0])
ostrokach
Saya menyukai ini lebih baik daripada jawaban yang diterima sebenarnya. Saya suka solusi oneline singkat.
Javier
13

Akan lebih mudah untuk membuat ulang bingkai data. Ini juga akan menafsirkan tipe kolom dari awal.

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

Anda dapat menentukan indeks baris di read_csv atau read_html konstruktor melalui headerparameter yang mewakili Row number(s) to use as the column names, and the start of the data. Ini memiliki keuntungan karena secara otomatis menjatuhkan semua baris sebelumnya yang seharusnya sampah.

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
sumber