Menghapus beberapa kolom berdasarkan nama kolom di Pandas

94

Saya memiliki beberapa data dan ketika saya mengimpornya saya mendapatkan kolom yang tidak dibutuhkan berikut ini, saya mencari cara mudah untuk menghapus semua ini

   'Unnamed: 24', 'Unnamed: 25', 'Unnamed: 26', 'Unnamed: 27',
   'Unnamed: 28', 'Unnamed: 29', 'Unnamed: 30', 'Unnamed: 31',
   'Unnamed: 32', 'Unnamed: 33', 'Unnamed: 34', 'Unnamed: 35',
   'Unnamed: 36', 'Unnamed: 37', 'Unnamed: 38', 'Unnamed: 39',
   'Unnamed: 40', 'Unnamed: 41', 'Unnamed: 42', 'Unnamed: 43',
   'Unnamed: 44', 'Unnamed: 45', 'Unnamed: 46', 'Unnamed: 47',
   'Unnamed: 48', 'Unnamed: 49', 'Unnamed: 50', 'Unnamed: 51',
   'Unnamed: 52', 'Unnamed: 53', 'Unnamed: 54', 'Unnamed: 55',
   'Unnamed: 56', 'Unnamed: 57', 'Unnamed: 58', 'Unnamed: 59',
   'Unnamed: 60'

Mereka diindeks oleh 0-indexing jadi saya mencoba sesuatu seperti

    df.drop(df.columns[[22, 23, 24, 25, 
    26, 27, 28, 29, 30, 31, 32 ,55]], axis=1, inplace=True)

Tapi ini tidak terlalu efisien. Saya mencoba menulis beberapa untuk loop tetapi ini menurut saya sebagai perilaku Panda yang buruk. Karenanya saya mengajukan pertanyaan di sini.

Saya telah melihat beberapa contoh yang serupa ( Jatuhkan beberapa kolom panda ) tetapi ini tidak menjawab pertanyaan saya.

Peadar Coyle
sumber
2
Apa maksudmu efisien? Apakah itu berjalan terlalu lambat? Jika masalah Anda adalah Anda tidak ingin mendapatkan indeks dari semua kolom yang ingin Anda hapus, perlu diketahui bahwa Anda hanya dapat memberikan df.dropdaftar nama kolom:df.drop(['Unnamed: 24', 'Unnamed: 25', ...], axis=1)
Carsten
Bukankah lebih mudah untuk hanya membuat subset kolom yang diinginkan: yaitu df = df[cols_of_interest], jika tidak, Anda dapat memotong df menurut kolom dan mendapatkan kolomnyadf.drop(df.ix[:,'Unnamed: 24':'Unnamed: 60'].head(0).columns, axis=1)
EdChum
2
Maksud saya tidak efisien dalam hal mengetik atau 'bau kode buruk'
Peadar Coyle
1
Mungkin perlu diperhatikan bahwa dalam banyak kasus, lebih mudah menyimpan kolom yang Anda inginkan kemudian menghapus kolom yang tidak Anda inginkan: df = df ['col_list']
sparrow

Jawaban:

65

Saya tidak tahu apa yang Anda maksud dengan tidak efisien tetapi jika yang Anda maksud dalam hal mengetik, bisa lebih mudah untuk hanya memilih kolom yang diminati dan menetapkan kembali ke df:

df = df[cols_of_interest]

Di mana cols_of_interestdaftar kolom yang Anda pedulikan.

Atau Anda dapat memotong kolom dan meneruskannya ke drop:

df.drop(df.ix[:,'Unnamed: 24':'Unnamed: 60'].head(0).columns, axis=1)

Panggilan untuk headhanya memilih 0 baris karena kami hanya tertarik pada nama kolom daripada data

memperbarui

Metode lain: Akan lebih mudah untuk menggunakan boolean mask str.containsdan membalikkannya untuk menutupi kolom:

In [2]:
df = pd.DataFrame(columns=['a','Unnamed: 1', 'Unnamed: 1','foo'])
df

Out[2]:
Empty DataFrame
Columns: [a, Unnamed: 1, Unnamed: 1, foo]
Index: []

In [4]:
~df.columns.str.contains('Unnamed:')

Out[4]:
array([ True, False, False,  True], dtype=bool)

In [5]:
df[df.columns[~df.columns.str.contains('Unnamed:')]]

Out[5]:
Empty DataFrame
Columns: [a, foo]
Index: []
EdChum
sumber
Saya mendapatkan kesalahan ketika saya mencoba melakukan salah satu ~ df.columns ... (TypeError: jenis operan buruk untuk unary ~: 'str') atau df.columns.str.contains ... (AttributeError: objek 'Index' tidak memiliki atribut 'str'). Ada ide mengapa ini mungkin terjadi?
Dai
@EdChum dapatkah saya membuat df = df [cols_of_interest] , di mana cols_of_interest menambahkan nama kolom ke dalamnya setiap kali perulangan for berulang?
@Victor tidak jika Anda melakukannya Anda menimpa dfdengan kolom baru Anda, Anda appendmungkin harus tetapi saya tidak benar-benar memahami pertanyaan Anda, Anda harus memposting pertanyaan nyata di SO daripada bertanya sebagai komentar karena itu formulir yang buruk di SO
EdChum
@Edm Anda benar. Saya telah membuat pertanyaan dan saya mencoba menyelesaikannya dengan mencari di berbagai bagian SO. Ini tautannya ! kontribusi apa pun akan membantu stackoverflow.com/questions/48923915/…
214

Sejauh ini pendekatan yang paling sederhana adalah:

yourdf.drop(['columnheading1', 'columnheading2'], axis=1, inplace=True)
Philipp Schwarz
sumber
1
Saya menggunakan format ini di beberapa kode saya dan saya mendapat SettingWithCopyWarningperingatan?
KillerSnail
2
@KillerSn, disimpan untuk diabaikan. Untuk menghindari kesalahan, coba: df = df.drop (['colheading1', 'colheading2'], axis = 1)
Philipp Schwarz
5
Istilah axismenjelaskan: stackoverflow.com/questions/22149584/… . Pada dasarnya, axis=0dikatakan "bijaksana kolom" dan axis=1"bijaksana baris".
Rohmer
5
Dan inplace=Trueberarti DataFramesudah dimodifikasi di tempat.
Rohmer
1
@Kernail jika Anda tidak ingin peringatan, lakukanyourdf = yourdf.drop(['columnheading1', 'columnheading2'], axis=1)
happy_sisyphus
41

Favorit pribadi saya, dan lebih mudah daripada jawaban yang saya lihat di sini (untuk beberapa kolom):

df.drop(df.columns[22:56], axis=1, inplace=True)

Atau membuat daftar untuk beberapa kolom.

col = list(df.columns)[22:56]
df.drop(col, axis=1, inplace=1)
sheldonzy
sumber
8
Ini harus menjadi jawabannya. Terbersih, termudah dibaca, dengan sintaks pengindeksan asli Pandas langsung.
Brent Faust
2
Jawaban ini harus memiliki tanda centang hijau di sebelahnya, bukan yang lain.
Siavosh Mahboubian
1
Koreksi kecil (kecuali saya salah): blok kode kedua harus memiliki 'inplace = True', bukan 'inplace = 1'.
Thredolsen
20

Ini mungkin cara yang baik untuk melakukan apa yang Anda inginkan. Ini akan menghapus semua kolom yang berisi 'Unnamed' di headernya.

for col in df.columns:
    if 'Unnamed' in col:
        del df[col]
knightofni
sumber
ini for col in df.columns:dapat disederhanakan for col in df:, juga OP belum menunjukkan skema penamaan apa untuk kolom lain, semuanya dapat berisi 'Tanpa Nama', juga ini tidak efisien karena menghapus kolom satu per satu
EdChum
Ini tentu saja tidak efisien, tetapi selama kami tidak mengerjakan kerangka data besar, itu tidak akan berdampak signifikan. Poin plus dari metode ini adalah mudah diingat dan cepat untuk membuat kode - sementara membuat daftar kolom yang ingin Anda simpan bisa sangat menyakitkan.
knightofni
Saya pikir ini mungkin paling berkinerja pada df besar karena Anda tidak perlu membuat salinan lokal denganinplace = True
Matt
13

Anda dapat melakukan ini dalam satu baris dan sekali jalan:

df.drop([col for col in df.columns if "Unnamed" in col], axis=1, inplace=True)

Ini melibatkan lebih sedikit pergerakan / penyalinan objek daripada solusi di atas.

Peter
sumber
11

Tidak yakin apakah solusi ini telah disebutkan di mana saja tetapi salah satu cara untuk melakukannya adalah pandas.Index.difference.

>>> df = pd.DataFrame(columns=['A','B','C','D'])
>>> df
Empty DataFrame
Columns: [A, B, C, D]
Index: []
>>> to_remove = ['A','C']
>>> df = df[df.columns.difference(to_remove)]
>>> df
Empty DataFrame
Columns: [B, D]
Index: []
px06
sumber
4

Anda bisa meneruskan nama kolom sebagai daftar dengan menentukan sumbu sebagai 0 atau 1

  • axis = 1: Sepanjang Baris
  • axis = 0: Sepanjang Kolom
  • Secara default sumbu = 0

    data.drop(["Colname1","Colname2","Colname3","Colname4"],axis=1)

Maddu Swaroop
sumber
4

Sederhana dan Mudah. Hapus semua kolom setelah tanggal 22.

df.drop(columns=df.columns[22:]) # love it
Niedson
sumber
Untuk memodifikasi dfdi tempat, tambahkan bendera inplace=True, Sehinggadf.drop(columns=df.columns[22:], inplace=True)
arilwan
1

Di bawah ini berhasil untuk saya:

for col in df:
    if 'Unnamed' in col:
        #del df[col]
        print col
        try:
            df.drop(col, axis=1, inplace=True)
        except Exception:
            pass
Shivgan
sumber
0

df = df[[col for col in df.columns if not ('Unnamed' in col)]]

Sarah
sumber
1
Ini mirip dengan Peter kecuali kolom yang tidak diinginkan disaring dan bukannya dibuang.
Sarah