パンダの列名に基づいて複数の列を削除する


94

私はいくつかのデータを持っています、そしてそれをインポートするとき、私はこれらのすべてを削除する簡単な方法を探している次の不要な列を取得します

   '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インデックスでインデックス付けされているので、次のようなものを試しました

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

しかし、これはあまり効率的ではありません。forループをいくつか書いてみましたが、これはパンダの動作が悪いと感じました。したがって、私はここで質問をします。

似たような例をいくつか見てきましたが(複数の列のパンダをドロップ)、これでは私の質問に答えられません。


2
効率的とはどういう意味ですか?実行速度が遅すぎませんか?あなたの問題は、あなたが、ノートはあなただけ与えることができますしてくださいことを削除したいことをすべての列のインデックスを取得したくないということであればdf.drop、列名のリストを:df.drop(['Unnamed: 24', 'Unnamed: 25', ...], axis=1)
カーステン

関心のある列をサブセット化するのは簡単ではないでしょうか。つまりdf = df[cols_of_interest]、そうでなければ、dfを列df.drop(df.ix[:,'Unnamed: 24':'Unnamed: 60'].head(0).columns, axis=1)
ごとに

2
私はタイピングまたは「悪いコードの臭い」の点で非効率的であることを意味しました
Peadar Coyle 2015

1
ほとんどの場合、必要な列を保持してから、不要な列を削除する方が簡単であることに注意してください。df= df ['col_list']
スズメ

回答:


65

非効率とはどういう意味かわかりませんが、入力に関しては、関心のある列を選択してdfに割り当てる方が簡単な場合があります。

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

〜df.columns ...(TypeError:単項のオペランドタイプが正しくありません〜: 'str')またはdf.columns.str.contains ...(AttributeError: 'Index'オブジェクトに属性がありません)のいずれかを実行しようとするとエラーが発生します'str')。なぜそうなるのか、何か考えはありますか?
ダイ

@EdChum df = df [cols_of_interest]を作成できますか?ここで、cols_of_interestは、forループが繰り返されるたびに列名を追加しますか?

@Victorいいえ、そうする場合はdf、新しい列で上書きする必要appendがありますが、私はあなたの質問を本当に理解していません
。SOの

@EdChumあなたは絶対に正しいです。私は質問を作成し、SOのさまざまな部分を検索して解決しようとしています。ここにリンクがあります!どんな貢献が役立ちますstackoverflow.com/questions/48923915/...を

212

はるかに簡単なアプローチは次のとおりです。

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

1
一部のコードでこの形式を使用しましたが、SettingWithCopyWarning警告が表示されますか?
KillerSnail 2017年

2
@KillerSnail、無視するのは保存です。エラーを回避するには、次のことを試してください。df= df.drop(['colheading1'、 'colheading2']、axis = 1)
Philipp Schwarz

5
axis説明されている用語:stackoverflow.com/questions/22149584/…。基本的に、axis=0「列方向」およびaxis=1「行方向」と呼ばれます。
ロメール2017年

5
そしてinplace=TrueDataFrameがその場で変更されることを意味します。
ロメール2017年

1
@Killernail警告が必要ない場合は、実行してくださいyourdf = yourdf.drop(['columnheading1', 'columnheading2'], axis=1)
happy_sisyphus 2017年

41

私の個人的なお気に入りであり、ここで見た回答よりも簡単です(複数の列の場合):

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

または、複数の列のリストを作成します。

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

8
これが答えになるはずです。わかりやすいネイティブのPandasインデックス構文を使用して、最もクリーンで読みやすい。
ブレントファウスト

2
この回答の横には、他の回答ではなく、緑色のチェックマークが付いているはずです。
SiavoshMahboubian19年

1
小さな修正(私が間違っていない限り):コードの2番目のブロックには「inplace = 1」ではなく「inplace = True」が必要です。
スレドルセン

20

これはおそらくあなたがやりたいことをするための良い方法です。ヘッダーに「Unnamed」を含むすべての列が削除されます。

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

これfor col in df.columns:は単純化できますfor col in df:。また、OPは他の列の命名スキームを示しておらず、すべてに「名前なし」が含まれている可能性があります。また、列を1つずつ削除するため、これは非効率的です
EdChum 2015

確かに効率的ではありませんが、巨大なデータフレームで作業していない限り、大きな影響はありません。この方法の利点は、覚えやすく、コーディングが速いことです。保持したい列のリストを作成するのは非常に面倒です。
knightofni 2015

ローカルコピーを作成する必要がないため、これは大きなdfで最もパフォーマンスが高いと思いますinplace = True
Matt

13

これは、1行で1回で実行できます。

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

これには、上記のソリューションよりもオブジェクトの移動/コピーが少なくて済みます。


11

この解決策がまだどこかで言及されているかどうかはわかりませんが、1つの方法はです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

軸を0または1として指定すると、列名をリストとして渡すことができます。

  • axis = 1:行に沿って
  • axis = 0:列に沿って
  • デフォルトではaxis = 0

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


4

シンプルで簡単。22日以降のすべての列を削除します。

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

そのdf場で変更するには、フラグを追加しますinplace=True。そのため、df.drop(columns=df.columns[22:], inplace=True)
arilwan

1

以下は私のために働いた:

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
これはPeterの場合と似ていますが、不要な列が削除されるのではなく除外される点が異なります。
サラ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.