Pandas'taki sütun adlarına göre birden çok sütunu silme


94

Bazı verilerim var ve bunları içe aktardığımda aşağıdaki gereksiz sütunları alıyorum, bunların hepsini silmenin kolay bir yolunu arıyorum

   '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'

0-indeksleme ile indeksleniyorlar, bu yüzden şöyle bir şey denedim

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

Ancak bu çok verimli değil. Bazı döngüler için yazmaya çalıştım ama bu beni Pandaların kötü davranışı olarak etkiledi. Dolayısıyla soruyu burada soruyorum.

Benzer bazı örnekler gördüm ( Birden fazla sütunlu pandayı bırakın ), ancak bu sorumu yanıtlamıyor.


2
Ne demek verimli? Çok yavaş mı çalışıyor? Eğer sorununuz, silmek istediğiniz tüm sütunların indislerini almak istemiyorsanız, lütfen sadece df.dropsütun adlarının bir listesini verebileceğinizi unutmayın :df.drop(['Unnamed: 24', 'Unnamed: 25', ...], axis=1)
Carsten

O sadece ilgi sütunları subsetine kolay olurdu: yani df = df[cols_of_interest]sütunları, aksi takdirde sütunlarla df doğrayabiliyordu ve almakdf.drop(df.ix[:,'Unnamed: 24':'Unnamed: 60'].head(0).columns, axis=1)
EdChum

2
Yazma veya 'kötü kod kokusu' açısından verimsizliği kastetmiştim
Peadar Coyle

1
Çoğu durumda, yalnızca istediğiniz sütunları tutup istemediklerinizi silmenin daha kolay olduğunu belirtmekte fayda var: df = df ['col_list']
sparrow

Yanıtlar:


65

Verimsiz derken neyi kastettiğinizi bilmiyorum, ancak yazmaktan bahsediyorsanız, sadece ilgilendiğiniz kolonları seçmek ve tekrar df'ye atamak daha kolay olabilir:

df = df[cols_of_interest]

Önem cols_of_interestverdiğiniz sütunların listesi nerede .

Veya sütunları dilimleyebilir ve bunu şuna iletebilirsiniz drop:

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

Çağrısı headsadece veriler yerine sütun adları ilgilendiğiniz 0 satırda olarak sadece seçer

Güncelleme

Başka bir yöntem: str.containsSütunları maskelemek için boole maskesini kullanmak ve tersine çevirmek daha kolay olacaktır :

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: []

~ Df.columns ... (TypeError: unary için kötü işlenen türü ~: 'str') veya df.columns.str.contains ... (AttributeError: 'Index' nesnesinin özniteliği yok) yapmayı denediğimde hata alıyorum "str"). Bunun neden olabileceğine dair bir fikriniz var mı?
Dai

@EdChum, df = df [cols_of_interest] oluşturabilir miyim , burada cols_of_interest bir for döngüsü yinelediğinde ona bir sütun adı ekler?

@Victor yapmanız hayır, siz bu üzerine yazmak o dfsize gereken yeni sütunla appendbelki ama gerçekten sorunuzu anlamıyorum, sen gerçek bir soru gönderebilir SO ziyade o kadar yoksul form olarak bir yorum olarak sormalısınız
EdChum

@EdChum kesinlikle haklısın. Soruyu ben oluşturdum ve SO'nun farklı kısımlarını arayarak çözmeye çalışıyorum. Bağlantı burada ! herhangi bir katkı stackoverflow.com/questions/48923915/… 'e

213

Açık farkla en basit yaklaşım şudur:

yourdf.drop(['columnheading1', 'columnheading2'], axis=1, inplace=True)

1
Bu formatı kodumun bir kısmında kullandım ve bir SettingWithCopyWarninguyarı alıyorum ?
KillerSnail

2
@KillerSnail, görmezden gelmek için kaydedilir. Hatayı önlemek için şunu deneyin: df = df.drop (['colheading1', 'colheading2'], axis = 1)
Philipp Schwarz

5
Açıklanan terim axis: stackoverflow.com/questions/22149584/… . Esasen, axis=0"sütun bazında" olduğu ve axis=1"satır bazında" olduğu söylenir .
Rohmer

5
Ve yerinde değiştirildiği inplace=Trueanlamına gelir DataFrame.
Rohmer

1
@Killernail uyarıyı istemiyorsan, yapyourdf = yourdf.drop(['columnheading1', 'columnheading2'], axis=1)
happy_sisyphus

41

Benim kişisel favorim ve burada gördüğüm cevaplardan daha kolay (birden fazla sütun için):

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

Veya birden çok sütun için bir liste oluşturmak.

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

8
Cevap bu olmalı. Basit yerel Pandas indeksleme sözdizimi ile en temiz, okunması en kolay.
Brent Faust

2
Bu cevabın yanında yeşil tik işareti olmalı, diğerlerinin değil.
Siavosh Mahboubian

1
Küçük düzeltme (yanılmıyorsam): ikinci kod bloğunun "inplace = 1" yerine "inplace = True" olması gerekir.
Thredolsen

20

Bu muhtemelen istediğini yapmanın iyi bir yoludur. Başlığında 'Adsız' bulunan tüm sütunları silecektir.

for col in df.columns:
    if 'Unnamed' in col:
        del df[col]

bu for col in df.columns:basitleştirilebilir for col in df:, ayrıca OP, diğer sütunlar için adlandırma şemasının ne olduğunu belirtmedi, hepsi 'Adsız' içerebilir, ayrıca bu, sütunları birer birer kaldırdığı için verimsizdir
EdChum

Kesinlikle verimli değil, ancak büyük veri çerçeveleri üzerinde çalışmadığımız sürece önemli bir etkisi olmayacak. Bu yöntemin artı noktası, hatırlaması kolay ve kodlamanın hızlı olmasıdır - saklamak istediğiniz sütunların bir listesini oluştururken oldukça zahmetli olabilir.
knightofni

Bence bu, büyük df'de en yüksek performansa sahip olacak çünkü yerel bir kopya yapmak zorunda değilsinizinplace = True
Matt

13

Bunu tek satırda ve tek seferde yapabilirsiniz:

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

Bu, yukarıdaki çözümlerden daha az nesnenin dolaşmasını / kopyalanmasını içerir.


11

Bu çözümden henüz herhangi bir yerde bahsedilip bahsedilmediğinden emin değilim, ancak yapmanın bir yolu 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: []

4

Ekseni 0 veya 1 olarak belirterek sütun adlarını bir liste olarak geçirebilirsiniz.

  • axis = 1: Satırlar Boyunca
  • eksen = 0: Sütunlar Boyunca
  • Varsayılan olarak eksen = 0

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


4

Basit ve kolay. Ayın 22'sinden sonra tüm sütunları kaldırın.

df.drop(columns=df.columns[22:]) # love it

dfYerinde değişiklik yapmak için bayrağı ekleyin inplace=True, Öyle kidf.drop(columns=df.columns[22:], inplace=True)
arilwan

1

Aşağıdakiler benim için çalıştı:

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

0

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


1
Bu, istenmeyen sütunların düşürülmesi yerine filtrelenmesi dışında Peter'ınkine benzer.
Sarah
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.