Pandas DataFrameから列を削除する


1331

DataFrameの列を削除するとき、私は次のように使用します。

del df['column_name']

そして、これはうまくいきます。以下を使用できないのはなぜですか?

del df.column_name

列/シリーズにとしてアクセスできるため、これが機能することdf.column_nameを期待していました。


2
この質問はMetaで議論されていることに注意してください。
RM

回答:


860

ご想像のとおり、正しい構文は

del df['column_name']

del df.column_namePythonの構文上の制限の結果として単に機能させることは困難です。Pythonのカバーの下でdel df[name]翻訳さdf.__delitem__(name)れます。


25
これは非常に古い「答え」であることに気づきましたが、私の好奇心はそそられます- なぜそれがPythonの構文上の制限なのですか?class A(object): def __init__(self): self.var = 1クラスを設定して、a = A(); del a.var
それで

14
@dwandersonの違いは、列を削除する場合、DataFrameは「方法」を独自に処理する必要があることです。の場合はdel df[name]df.__delitem__(name)DataFrameが実装して必要に応じて変更できるメソッドに変換されます。の場合、del df.nameカスタム変数が実行される機会なしにメンバー変数が削除されます。あなた自身の例を考えてみてください-あなたdel a.varは「変数を削除する」という結果を得ることができますか?できれば教えてください。できません:)
ヨナタン


5
@Yonatan EugeneのコメントはPython 2にも適用されます。ディスクリプターは2.2以降Python 2にあり、要件を満たすのは簡単です;)
CS

1
この答えは正確ではありません- pandas開発者はそうはありませんでしたが、それが難しいことを意味するわけではありません。
wizzwizz4

2185

パンダでこれを行う最良の方法は、使用することdropです:

df = df.drop('column_name', 1)

ここで、1ある軸の数(0行および1列に対しては)。

再割り当てせずに列を削除するには、次のようにしますdf

df.drop('column_name', axis=1, inplace=True)

最後に、列ラベルではなく列番号でドロップするには、これを試して、たとえば1番目、2番目、4番目の列を削除します。

df = df.drop(df.columns[[0, 1, 3]], axis=1)  # df.columns is zero-based pd.Index 

列の「テキスト」構文も使用します。

df.drop(['column_nameA', 'column_nameB'], axis=1, inplace=True)

79
これdelは何らかの理由で推奨されますか?
beardc 2013

20
この削除方法にはメリットがありますが、この回答は、質問の答えにはなりません。
ポール

109
確かに@Paulですが、質問のタイトルのため、ここに到着するほとんどの人は列を削除する方法を考え出そうとします。
LondonRob 2014年

24
@beardcの別の利点drop上はdelつまりdrop、あなたが(特に3-Dマトリックスのために有用な、または任意の軸に沿って操作インプレースか否か、また、削除レコードを、一度に複数の列を削除実行することを可能にするPanel
ホブ

8
もう一つの利点drop以上はdelつまりドロップがパンダAPIの一部であり、ドキュメントが含まれています。
modulitos

242

使用する:

columns = ['Col1', 'Col2', ...]
df.drop(columns, inplace=True, axis=1)

これにより、1つ以上の列がインプレースで削除されます。inplace=Truepandas v0.13で追加され、古いバージョンでは動作しないことに注意してください。その場合、結果を割り当てる必要があります。

df = df.drop(columns, axis=1)

3
この回答に関するメモ:「リスト」を使用する場合、角括弧は削除する必要があります:df.drop(list,inplace=True,axis=1)
edesz

1
これは、この方法の優位性が明らかになるため、実際に受け入れられる答えになるはずdelです。一度に複数の列をドロップする可能性があります。
dbliss 2017

111

インデックスでドロップ

1列目、2列目、4列目を削除します。

df.drop(df.columns[[0,1,3]], axis=1, inplace=True)

最初の列を削除:

df.drop(df.columns[[0]], axis=1, inplace=True)

inplaceコピーを作成せずに元のデータを変更できるように、オプションのパラメーターがあります。

ポップ

列の選択、追加、削除

列を削除column-name

df.pop('column-name')

例:

df = DataFrame.from_items([('A', [1, 2, 3]), ('B', [4, 5, 6]), ('C', [7,8, 9])], orient='index', columns=['one', 'two', 'three'])

print df

   one  two  three
A    1    2      3
B    4    5      6
C    7    8      9

df.drop(df.columns[[0]], axis=1, inplace=True) print df

   two  three
A    2      3
B    5      6
C    8      9

three = df.pop('three') print df

   two
A    2
B    5
C    8

1
パンダで行をポップするにはどうすればよいですか?
ケネットセレステ

2
@Yugi転置したデータフレームを使用できます。EX - df.T.pop('A')
クロックスレーブ

@ClockSlave元のを変更しませんdf。あなたがすることdf = df.T; df.pop(index); df = df.Tできますが、これは過度に思えます。
cs95

代わりにdf.drop(df.columns[[0]], axis=1, inplace=True)それを使用するのに十分で はないでしょうdf.drop([0], axis=1)か?
Anirban Mukherjee

1
@Anirban Mukherjee場合によります。列名を削除したい場合は0df.drop(0, axis=1)うまくいきます。ただし、列名がわからず、最初の列を削除してからが必要な場合はdf.drop(df.columns[[0]], axis=1, inplace=True)、位置で最初の列を選択してドロップします。
jezrael

71

ここでのほとんどの回答で見逃された実際の質問は次のとおりです。

なぜ使用できないのdel df.column_nameですか?

最初に問題を理解する必要があります。これには、Pythonマジックメソッドに飛び込む必要があります

ウェスが指摘するように、彼の答えはでdel df['column']のpythonにマップマジックメソッド df.__delitem__('column')されて列を削除するパンダに実装します

しかし、約上記のリンクで指摘Pythonの魔法の方法

実際、__del__それが呼び出される不安定な状況のため、ほとんど使用すべきではありません。注意して使用してください!

あなたはdel df['column_name']それを使用したり奨励したりdel df.column_nameすべきではなく、それによって考慮すべきではないと主張することができます。

ただし、理論的にdel df.column_name魔法の方法__delattr__を使用してパンダで動作するように実装できます。ただし、これにより特定の問題が発生します。del df['column_name']実装にはすでに問題がありますが、程度は低いです。

問題の例

「dtypes」または「columns」と呼ばれるデータフレームに列を定義するとどうなりますか?

次に、これらの列を削除するとします。

del df.dtypes__delattr__「dtypes」属性または「dtypes」列を削除する必要があるかのように、メソッドを混乱させます。

この問題の背後にあるアーキテクチャの質問

  1. データフレームは列のコレクションですか?
  2. データフレームは行のコレクションですか?
  3. 列はデータフレームの属性ですか?

パンダの答え:

  1. はい、あらゆる点で
  2. いいえ。ただし、必要に応じて.ix.locまたは.ilocメソッドを使用できます。
  3. たぶん、あなたデータを読みたいですか?次に、yesただし、属性の名前がデータフレームに属する別の属性によってすでに使用されている場合を除きます。データを変更しますか?その後、いいえ

TLDR;

del df.column_nameこのような認知的不協和がユーザーに発生しないようにするために、パンダは非常に乱暴に成長したアーキテクチャを再検討する必要があるため、これを行うことはできません。

Protip:

df.column_nameは使用しないでください。見栄えは良いかもしれませんが、認知的不協和が発生します

ここに収まるZen of Pythonの引用:

列を削除する方法は複数あります。

それを行うには、明白な方法が1つ(できれば1つだけ)あるはずです。

列は属性である場合とそうでない場合があります。

特別なケースは、ルールを破るほど特別ではありません。

del df.dtypesdtypes属性またはdtypes列を削除しますか?

あいまいな状況に直面して、推測する誘惑を拒否してください。


「実際には、__del__それが呼び出される不安定な状況のため、ほとんど使用すべきではありません。注意して使用してください!」ここで使用されているメソッドはなので、ここでは完全に無関係です__delattr__
pppery

1
@ppperry引用ミスです。それはですdel意味する組み込み、ない.__del__インスタンスメソッド。del組み込みはにマッピングしている__delattr____delitem__私は上の私の議論を構築しています何です。だから、多分あなたは私が書いたものをもう一度読みたいと思うでしょう。
firelynx

1
__... __はStackExchangeによって太字のマークアップとして解釈されます
pppery

2
「df.column_nameを使用しないでください。見た目はきれいですが、認知的不協和が発生します」これはどういう意味ですか?私は心理学者ではないので、これを調べてあなたの意味を理解する必要があります。また、パンダで同じことを行うには何百もの有効な方法があるため、Zenを引用しても意味がありません。
cs95

58

すばらしい追加は、列が存在する場合にのみ列ドロップする機能です。このようにして、より多くのユースケースをカバーでき、渡されたラベルから既存の列のみを削除します。

たとえば、単純にerrors = 'ignore'を追加します。

df.drop(['col_name_1', 'col_name_2', ..., 'col_name_N'], inplace=True, axis=1, errors='ignore')
  • これは、pandas 0.16.1以降の新機能です。ドキュメントはこちらです。

41

あなたができるバージョン0.16.1から

df.drop(['column_name'], axis = 1, inplace = True, errors = 'ignore')

3
そして、これはまた、(すなわち、エラーを出さずに存在する必要はありませんいくつかは、複数の列を落とすサポートerrors= 'ignore'df.drop(['column_1','column_2'], axis=1 , inplace=True,errors= 'ignore')などのアプリケーションが必要であれば、!
ミュオン2016年

31

常に[]表記法を使用することをお勧めします。1つの理由は、df.column_name番号付きインデックスに対して属性表記()が機能しないことです。

In [1]: df = DataFrame([[1, 2, 3], [4, 5, 6]])

In [2]: df[1]
Out[2]:
0    2
1    5
Name: 1

In [3]: df.1
  File "<ipython-input-3-e4803c0d1066>", line 1
    df.1
       ^
SyntaxError: invalid syntax

26

パンダ0.21+答え

Pandasバージョン0.21では、およびメソッドのシグネチャと一致するようにおよびパラメータのdrop両方が含まれるようにメソッドが少し変更されました。indexcolumnsrenamereindex

df.drop(columns=['column_a', 'column_c'])

個人的にaxisは、ほとんどすべてのパンダメソッドで使用される主要なキーワードパラメーターであるため、列またはインデックスを示すためにパラメーターを使用することを好みます。しかし、バージョン0.21では、いくつかの選択肢が追加されています。


1
df.drop(['column_a'、 'column_c']、axis = 1)| それは今のところ私のために働いています
YouAreAwesome 2018

21

パンダ0.16.1以降では、@ eiTanLaViによって投稿されたソリューションごとに列が存在する場合にのみ、列をドロップできます。そのバージョンの前は、条件付きリスト内包表記を使用して同じ結果を得ることができます。

df.drop([col for col in ['col_name_1','col_name_2',...,'col_name_N'] if col in df], 
        axis=1, inplace=True)

14

TL; DR

わずかに効率的なソリューションを見つけるための多くの努力。追加された複雑さを正当化することは困難ですが、df.drop(dlst, 1, errors='ignore')

df.reindex_axis(np.setdiff1d(df.columns.values, dlst), 1)

プリアンブル
列を削除することは、他の列を選択することと意味的に同じです。考慮すべき追加の方法をいくつか示します。

また、一度に複数の列を削除し、存在しない列を削除するための一般的な解決策にも焦点を当てます。

これらのソリューションの使用は一般的であり、単純なケースでも機能します。


セットアップを
検討し、pd.DataFrame df削除するリストdlst

df = pd.DataFrame(dict(zip('ABCDEFGHIJ', range(1, 11))), range(3))
dlst = list('HIJKLM')

df

   A  B  C  D  E  F  G  H  I   J
0  1  2  3  4  5  6  7  8  9  10
1  1  2  3  4  5  6  7  8  9  10
2  1  2  3  4  5  6  7  8  9  10

dlst

['H', 'I', 'J', 'K', 'L', 'M']

結果は次のようになります。

df.drop(dlst, 1, errors='ignore')

   A  B  C  D  E  F  G
0  1  2  3  4  5  6  7
1  1  2  3  4  5  6  7
2  1  2  3  4  5  6  7

列を削除することは他の列を選択することと同じなので、次の2つのタイプに分けます。

  1. ラベルの選択
  2. ブール選択

ラベルの選択

削除したい列なしで、保持したい列を表すラベルのリスト/配列を作成することから始めます。

  1. df.columns.difference(dlst)

    Index(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype='object')
  2. np.setdiff1d(df.columns.values, dlst)

    array(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype=object)
  3. df.columns.drop(dlst, errors='ignore')

    Index(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype='object')
  4. list(set(df.columns.values.tolist()).difference(dlst))

    # does not preserve order
    ['E', 'D', 'B', 'F', 'G', 'A', 'C']
  5. [x for x in df.columns.values.tolist() if x not in dlst]

    ['A', 'B', 'C', 'D', 'E', 'F', 'G']

ラベルの列
選択プロセスを比較するために、次のことを前提としています。

 cols = [x for x in df.columns.values.tolist() if x not in dlst]

次に評価できます

  1. df.loc[:, cols]
  2. df[cols]
  3. df.reindex(columns=cols)
  4. df.reindex_axis(cols, 1)

これらはすべて次のように評価されます。

   A  B  C  D  E  F  G
0  1  2  3  4  5  6  7
1  1  2  3  4  5  6  7
2  1  2  3  4  5  6  7

ブールスライス

スライスするためのブール値の配列/リストを作成できます

  1. ~df.columns.isin(dlst)
  2. ~np.in1d(df.columns.values, dlst)
  3. [x not in dlst for x in df.columns.values.tolist()]
  4. (df.columns.values[:, None] != dlst).all(1)

ブール値からの列
比較のため

bools = [x not in dlst for x in df.columns.values.tolist()]
  1. df.loc[: bools]

これらはすべて次のように評価されます。

   A  B  C  D  E  F  G
0  1  2  3  4  5  6  7
1  1  2  3  4  5  6  7
2  1  2  3  4  5  6  7

堅牢なタイミング

機能

setdiff1d = lambda df, dlst: np.setdiff1d(df.columns.values, dlst)
difference = lambda df, dlst: df.columns.difference(dlst)
columndrop = lambda df, dlst: df.columns.drop(dlst, errors='ignore')
setdifflst = lambda df, dlst: list(set(df.columns.values.tolist()).difference(dlst))
comprehension = lambda df, dlst: [x for x in df.columns.values.tolist() if x not in dlst]

loc = lambda df, cols: df.loc[:, cols]
slc = lambda df, cols: df[cols]
ridx = lambda df, cols: df.reindex(columns=cols)
ridxa = lambda df, cols: df.reindex_axis(cols, 1)

isin = lambda df, dlst: ~df.columns.isin(dlst)
in1d = lambda df, dlst: ~np.in1d(df.columns.values, dlst)
comp = lambda df, dlst: [x not in dlst for x in df.columns.values.tolist()]
brod = lambda df, dlst: (df.columns.values[:, None] != dlst).all(1)

テスト中

res1 = pd.DataFrame(
    index=pd.MultiIndex.from_product([
        'loc slc ridx ridxa'.split(),
        'setdiff1d difference columndrop setdifflst comprehension'.split(),
    ], names=['Select', 'Label']),
    columns=[10, 30, 100, 300, 1000],
    dtype=float
)

res2 = pd.DataFrame(
    index=pd.MultiIndex.from_product([
        'loc'.split(),
        'isin in1d comp brod'.split(),
    ], names=['Select', 'Label']),
    columns=[10, 30, 100, 300, 1000],
    dtype=float
)

res = res1.append(res2).sort_index()

dres = pd.Series(index=res.columns, name='drop')

for j in res.columns:
    dlst = list(range(j))
    cols = list(range(j // 2, j + j // 2))
    d = pd.DataFrame(1, range(10), cols)
    dres.at[j] = timeit('d.drop(dlst, 1, errors="ignore")', 'from __main__ import d, dlst', number=100)
    for s, l in res.index:
        stmt = '{}(d, {}(d, dlst))'.format(s, l)
        setp = 'from __main__ import d, dlst, {}, {}'.format(s, l)
        res.at[(s, l), j] = timeit(stmt, setp, number=100)

rs = res / dres

rs

                          10        30        100       300        1000
Select Label                                                           
loc    brod           0.747373  0.861979  0.891144  1.284235   3.872157
       columndrop     1.193983  1.292843  1.396841  1.484429   1.335733
       comp           0.802036  0.732326  1.149397  3.473283  25.565922
       comprehension  1.463503  1.568395  1.866441  4.421639  26.552276
       difference     1.413010  1.460863  1.587594  1.568571   1.569735
       in1d           0.818502  0.844374  0.994093  1.042360   1.076255
       isin           1.008874  0.879706  1.021712  1.001119   0.964327
       setdiff1d      1.352828  1.274061  1.483380  1.459986   1.466575
       setdifflst     1.233332  1.444521  1.714199  1.797241   1.876425
ridx   columndrop     0.903013  0.832814  0.949234  0.976366   0.982888
       comprehension  0.777445  0.827151  1.108028  3.473164  25.528879
       difference     1.086859  1.081396  1.293132  1.173044   1.237613
       setdiff1d      0.946009  0.873169  0.900185  0.908194   1.036124
       setdifflst     0.732964  0.823218  0.819748  0.990315   1.050910
ridxa  columndrop     0.835254  0.774701  0.907105  0.908006   0.932754
       comprehension  0.697749  0.762556  1.215225  3.510226  25.041832
       difference     1.055099  1.010208  1.122005  1.119575   1.383065
       setdiff1d      0.760716  0.725386  0.849949  0.879425   0.946460
       setdifflst     0.710008  0.668108  0.778060  0.871766   0.939537
slc    columndrop     1.268191  1.521264  2.646687  1.919423   1.981091
       comprehension  0.856893  0.870365  1.290730  3.564219  26.208937
       difference     1.470095  1.747211  2.886581  2.254690   2.050536
       setdiff1d      1.098427  1.133476  1.466029  2.045965   3.123452
       setdifflst     0.833700  0.846652  1.013061  1.110352   1.287831

fig, axes = plt.subplots(2, 2, figsize=(8, 6), sharey=True)
for i, (n, g) in enumerate([(n, g.xs(n)) for n, g in rs.groupby('Select')]):
    ax = axes[i // 2, i % 2]
    g.plot.bar(ax=ax, title=n)
    ax.legend_.remove()
fig.tight_layout()

これは、実行にかかる時間に関連していますdf.drop(dlst, 1, errors='ignore')。結局のところ、私たちはパフォーマンスを適度に向上させるだけのようです。

ここに画像の説明を入力してください

事実ならば、最良の解決策は、使用reindexreindex_axisハックにlist(set(df.columns.values.tolist()).difference(dlst))。近い秒ですが、それでも非常にわずかに優れてdropnp.setdiff1dます。

rs.idxmin().pipe(
    lambda x: pd.DataFrame(
        dict(idx=x.values, val=rs.lookup(x.values, x.index)),
        x.index
    )
)

                      idx       val
10     (ridx, setdifflst)  0.653431
30    (ridxa, setdifflst)  0.746143
100   (ridxa, setdifflst)  0.816207
300    (ridx, setdifflst)  0.780157
1000  (ridxa, setdifflst)  0.861622

2

ドット構文はJavaScriptでは機能しますが、Pythonでは機能しません。

  • Python: del df['column_name']
  • JavaScript:del df['column_name'] または del df.column_name

2

元のデータフレームdfが大きすぎず、メモリの制約がなく、いくつかの列を保持するだけでよい場合は、必要な列のみを含む新しいデータフレームを作成することもできます。

new_df = df[['spam', 'sausage']]

2

drop()メソッドを使用して、指定した列または特定の列を削除または削除できます。

仮定DFはデータフレームです。

削除する列= column0

コード:

df = df.drop(column0, axis=1)

複数の列col1、col2 、. 。。、coln、リストから削除する必要があるすべての列を挿入する必要があります。次に、それらをdrop()メソッドで削除します。

コード:

df = df.drop([col1, col2, . . . , coln], axis=1)

お役に立てれば幸いです。


df = df.drop([col1, col2, . . . , coln], axis=1)col1、col2などの代わりに変数名を指定すると、これは機能しません。間違いなく存在する場合、軸にないエラー列が表示されます。@Littin助けてくれませんか?
RSM

1

Pandas DataFrameで列を削除する別の方法

インプレース削除を探していない場合は、DataFrame(...)関数as を使用して列を指定することにより、新しいDataFrameを作成できます。

my_dict = { 'name' : ['a','b','c','d'], 'age' : [10,20,25,22], 'designation' : ['CEO', 'VP', 'MD', 'CEO']}

df = pd.DataFrame(my_dict)

新しいDataFrameを次のように作成します

newdf = pd.DataFrame(df, columns=['name', 'age'])

あなたはデル/ドロップで得られるものと同じくらい良い結果を得る


1
これは技術的には正しいですが、削除する1つ(またはいくつか)の列だけではなく、保持するすべての列をリストする必要があるのはばかげているようです。
cs95
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.