Xóa nhiều cột dựa trên tên cột trong Pandas


95

Tôi có một số dữ liệu và khi nhập dữ liệu đó, tôi nhận được các cột không cần thiết sau. Tôi đang tìm một cách dễ dàng để xóa tất cả

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

Chúng được lập chỉ mục bằng cách lập chỉ mục 0, vì vậy tôi đã thử một cái gì đó như

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

Nhưng điều này không hiệu quả lắm. Tôi đã thử viết một số vòng lặp for nhưng điều này khiến tôi coi là hành vi xấu của Gấu trúc. Do đó tôi đặt câu hỏi ở đây.

Tôi đã thấy một số ví dụ tương tự ( Thả nhiều cột gấu trúc ) nhưng điều này không trả lời câu hỏi của tôi.


2
Ý bạn là gì, hiệu quả? Nó chạy quá chậm? Nếu vấn đề của bạn là bạn không muốn nhận các chỉ số của tất cả các cột mà bạn muốn xóa, xin lưu ý rằng bạn chỉ có thể cung cấp df.dropdanh sách các tên cột:df.drop(['Unnamed: 24', 'Unnamed: 25', ...], axis=1)
Carsten

Sẽ không dễ dàng hơn nếu chỉ đặt con các cột quan tâm: tức là df = df[cols_of_interest], nếu không, bạn có thể cắt df theo các cột và lấy các cộtdf.drop(df.ix[:,'Unnamed: 24':'Unnamed: 60'].head(0).columns, axis=1)
EdChum 16/02/15

2
Tôi có nghĩa là không hiệu quả về mặt đánh máy hoặc 'mùi mã xấu'
Peadar Coyle

1
Có thể là đáng chú ý là trong nhiều trường hợp nó dễ dàng hơn chỉ để giữ cho cột mà bạn muốn sau đó xóa những cái mà bạn làm không: df = df [ 'col_list']
Chim sẻ

Câu trả lời:


65

Tôi không biết ý của bạn là không hiệu quả nhưng nếu bạn muốn nói về cách gõ thì có thể dễ dàng hơn chỉ cần chọn cols quan tâm và gán lại cho df:

df = df[cols_of_interest]

Trong trường hợp cols_of_interestlà một danh sách các cột mà bạn quan tâm.

Hoặc bạn có thể cắt các cột và chuyển nó đến drop:

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

Lời kêu gọi headchỉ chọn 0 hàng vì chúng tôi chỉ quan tâm đến tên cột hơn là dữ liệu

cập nhật

Một phương pháp khác: Sẽ đơn giản hơn nếu sử dụng mặt nạ boolean từ str.containsvà đảo ngược nó để che các cột:

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

Tôi gặp lỗi khi thử thực hiện ~ df.columns ... (TypeError: loại toán hạng không hợp lệ cho một ngôi ~: 'str') hoặc df.columns.str.contains ... (AttributeError: Đối tượng 'Index' không có thuộc tính 'str'). Vài ý tưởng tại sao nó như thế?
Dai

@EdChum Tôi có thể tạo df = df [cols_of_interest] , trong đó cols_of_interest thêm tên cột vào nó mỗi khi lặp lại vòng lặp for không?

@Victor không nếu bạn làm như vậy là bạn ghi đè lên dfcột mới của mình, appendcó lẽ bạn nên nhưng tôi không thực sự hiểu câu hỏi của bạn, bạn nên đăng một câu hỏi thực sự trên SO hơn là hỏi dưới dạng nhận xét vì nó có hình thức kém trên SO
EdChum

@EdChum bạn hoàn toàn đúng. Tôi đã tạo câu hỏi và tôi đang cố gắng giải quyết bằng cách tìm kiếm các phần khác nhau của SO. Đây là liên kết! mọi đóng góp sẽ giúp stackoverflow.com/questions/48923915/…

214

Cho đến nay, cách tiếp cận đơn giản nhất là:

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

1
Tôi đã sử dụng định dạng này trong một số mã của mình và tôi nhận được SettingWithCopyWarningcảnh báo?
KillerSnail

2
@KillerSnail, thật tiết kiệm nếu bỏ qua. Để tránh lỗi, hãy thử: df = df.drop ([ 'colheading1', 'colheading2'], axis = 1)
Philipp Schwarz

5
Thuật ngữ được axisgiải thích: stackoverflow.com/questions/22149584/… . Về cơ bản, axis=0được cho là "khôn ngoan theo cột" và axis=1"khôn ngoan theo hàng".
Rohmer

5
inplace=Truecó nghĩa DataFramelà được sửa đổi tại chỗ.
Rohmer

1
@Killernail nếu bạn không muốn cảnh báo, làmyourdf = yourdf.drop(['columnheading1', 'columnheading2'], axis=1)
happy_sisyphus

41

Yêu thích cá nhân của tôi và dễ hơn những câu trả lời tôi đã thấy ở đây (cho nhiều cột):

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

Hoặc tạo danh sách cho nhiều cột.

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

8
Đây nên là câu trả lời. Rõ ràng nhất, dễ đọc nhất, với cú pháp lập chỉ mục Pandas bản địa đơn giản.
Brent Faust

2
Câu trả lời này phải có dấu tích màu xanh lá cây bên cạnh nó, không phải những người khác.
Siavosh Mahboubian

1
Điều chỉnh nhỏ (trừ khi tôi nhầm): khối mã thứ hai phải có 'inplace = True' thay vì 'inplace = 1'.
Thredolsen

20

Đây có lẽ là một cách tốt để làm những gì bạn muốn. Nó sẽ xóa tất cả các cột có chứa 'Không tên' trong tiêu đề của chúng.

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

điều này for col in df.columns:có thể được đơn giản hóa thành for col in df:, OP cũng không chỉ ra lược đồ đặt tên cho các cột khác là gì, tất cả chúng đều có thể chứa 'Không tên', điều này cũng không hiệu quả vì nó xóa từng cột một
EdChum 16/02/15

Nó chắc chắn không hiệu quả, nhưng miễn là chúng tôi không làm việc trên các khung dữ liệu lớn thì nó sẽ không có tác động đáng kể. Điểm cộng của phương pháp này là nó đơn giản để nhớ và viết mã nhanh - trong khi việc tạo danh sách các cột bạn muốn giữ lại có thể khá khó khăn.
Knightofni

Tôi nghĩ rằng điều này có thể hoạt động hiệu quả nhất trên df lớn vì bạn không phải tạo bản sao cục bộ vớiinplace = True
Matt

13

Bạn có thể làm điều này trong một dòng và một lần:

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

Điều này liên quan đến việc di chuyển / sao chép đối tượng ít hơn so với các giải pháp ở trên.


11

Không chắc liệu giải pháp này đã được đề cập ở đâu chưa nhưng có một cách để làm là 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

Bạn chỉ có thể chuyển tên cột dưới dạng danh sách với việc chỉ định trục là 0 hoặc 1

  • axis = 1: Dọc theo hàng
  • axis = 0: Dọc theo các cột
  • Theo mặc định trục = 0

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


4

Đơn giản và dễ dàng. Xóa tất cả các cột sau ngày 22.

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

Để sửa đổi dftại chỗ, hãy thêm cờ inplace=True, Vì vậydf.drop(columns=df.columns[22:], inplace=True)
arilwan

1

Những điều dưới đây phù hợp với tôi:

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
Điều này tương tự như của Peter ngoại trừ việc các cột không mong muốn được lọc ra thay vì bị loại bỏ.
Sarah
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.