2015-02-16 4 views
35

У меня есть некоторые данные, и когда я импортировать его я получаю следующие ненужные столбцы Я ищу простой способ, чтобы удалить все этиУдаление нескольких столбцов на основе имен столбцов в панд

'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-indexing, поэтому я попробовал что-то вроде

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

Но это не очень эффективно. Я попробовал написать некоторые для циклов, но это показалось мне плохим поведением Панд. Поэтому я задаю этот вопрос.

Я видел несколько примеров, похожих на (Drop multiple columns pandas), но это не отвечает на мой вопрос.

+2

Что вы имеете в виду, эффективно? Он работает слишком медленно? Если ваша проблема в том, что вы не хотите получать индексы всех столбцов, которые хотите удалить, обратите внимание, что вы можете просто дать 'df.drop' список имен столбцов:' df.drop (['Без имени : 24 ',' Без имени: 25 ', ...], axis = 1) ' – Carsten

+0

Было бы проще просто подобрать интересующие столбцы: ie' df = df [cols_of_interest] ', иначе вы могли бы нарезать df по столбцам и получить столбцы' df.drop (df. ix [:, 'Без имени: 24': 'Без имени: 60']. head (0) .columns, axis = 1) ' – EdChum

+1

Я имел в виду неэффективность с точки зрения ввода или« плохого запаха кода » –

ответ

20

Я не знаю, что вы имеете в виду неэффективно, но если вы имеете в виду с точки зрения печатая это может быть проще просто выбрать COLS интереса и присвоить обратно к ДФ:

df = df[cols_of_interest] 

Где cols_of_interest является список столбцов, о которых вы заботитесь.

Или вы можете нарезать столбцы и передать это drop:

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

Вызов head просто выбирает 0 строк, как мы заинтересованы только в названиях столбцов, а не данные

обновление

Другим методом было бы проще использовать булевую маску от str.contains и инвертировать ее для маскировки столбцов:

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

Я получаю ошибки при попытке либо ~ df.columns ... (TypeError: неправильный тип операнда для унарного ~: 'str') или df.columns.str.contains ... (AttributeError: объект 'Index' не имеет атрибута 'str'). Есть идеи, почему это может быть? – Dai

+0

Помощник Downvoter для объяснения – EdChum

+0

@EdChum можно создать __df = df [cols_of_interest] __, где __cols_of_interest__ добавляет к нему имя столбца каждый раз, когда цикл цикла повторяется? – Victor

12

Это, вероятно, хороший способ сделать то, что вы хотите. Он удалит все столбцы, содержащие «Безымянный» в заголовке.

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

this 'for col in df.columns:' может быть упрощено до 'для col в df:', также OP не указал, что схема именования для других столбцов, они могут содержать «Безымянный», также это неэффективно, поскольку он удаляет столбцы по одному за раз – EdChum

+0

Это, конечно, неэффективно, но пока мы не работаем над огромными кадрами данных, это не окажет существенного влияния. Плюсом этого метода является то, что его легко запомнить и быстро выполнить код - при создании списка столбцов, которые вы хотите сохранить, может быть довольно болезненно. – knightofni

0

Ниже работал для меня:

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

Побочный далеко самый простой подход:

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

Я использовал этот формат в некоторых своих кодах, и я получаю предупреждение «SettingWithCopyWarning»? – KillerSnail

+0

@KillerSnail, это сохранить, чтобы игнорировать. Чтобы избежать ошибки, попробуйте: df = df.drop (['colheading1', 'colheading2'], axis = 1) –

+0

Объяснение термина 'axis': https://stackoverflow.com/questions/22149584/what-does- ось-в-панды-средний. По сути, 'axis = 0' называется« по столбцу », а' axis = 1' является «по ряду». – Rohmer

4

Вы можете сделать это в одной строке и один раз:

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

Это связано с меньшим перемещением/копированием o чем решения выше.

7

Мой личный фаворит, и проще, чем ответы, которые я видел здесь (для нескольких столбцов):

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

Или создать список для нескольких столбцов.

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

Это должен быть ответ. Самый чистый, самый простой для чтения, с простым синтаксисом индексации Pandas. –

Смежные вопросы