追加 - python 行 削除 条件




del df.column_nameを使用してpandas DataFrameから列を削除する (10)

TL; DR

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

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

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

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

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

セットアップ
pd.DataFrame dfdlstを削除するリストを検討してください

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)

Booleanからの列
比較のために

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')を実行するのにかかる時間にdf.drop(dlst, 1, errors='ignore')します。 それはすべての努力の後で、我々は穏やかにパフォーマンスを向上させるようです。

事実、最良のソリューションがハックlist(set(df.columns.values.tolist()).difference(dlst)) reindexまたはreindex_axisを使用する場合list(set(df.columns.values.tolist()).difference(dlst)) 。 2番目に近い、まだdropよりもずっと良い点はnp.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

DataFrameの列を削除するときは、次のものを使用します。

del df['column_name']

そして、これは素晴らしい作品です。 なぜ私は以下を使用できないのですか?

del df.column_name

df.column_nameとして/ Seriesをアクセスできるので、これがdf.column_nameと思います。


パンダ0.21+答え

Pandasバージョン0.21では、 renameメソッドと再indexメソッドのシグネチャと一致するindexパラメータとcolumnsパラメータの両方を含めるように、 dropメソッドがわずかに変更されました。

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

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


@ eiTanLaViによって投稿されたソリューションごとに存在する場合のみ、パンダ0.16.1+で列を削除できます。 そのバージョンより前には、条件付きリストの理解度を使用して同じ結果を得ることができます。

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

del df.column_name単にPythonの構文上の制限の結果としてdel df.column_nameさせるのは難しいです。 del df[name]はPythonのカバーの下でdf.__delitem__(name)変換されます。


つかいます:

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

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

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

データフレーム( df )から単一の列( col_name )を削除する場合は、次のいずれかを試してください。

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

または

df.drop(col_name, axis=1, inplace=True)

データフレーム( df )から列のリスト( col_lst = [col_name_1,col_name_2,...] )を削除する場合は、次のいずれかを試してください。

df.drop(col_lst, axis=1, inplace=True)

または

df.drop(columns=col_lst, inplace=True)

バージョン0.16.1から行うことができます

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

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

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

1番号です(行は0 、列は1 )。

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

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

最後に、列ラベルではなく列番号で削除するには、削除するにはこれを試してください(例:1,2番目と4番目の列)。

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

実際の質問は、ここでのほとんどの回答が欠けている:

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

最初に私たちはこの問題を理解する必要があります。そのためには、 Pythonの魔法の方法没頭する必要があります

Wesが答えで指摘しているように、 del df['column']はpythonのマジックメソッド df.__delitem__('column')マップされています。これは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は、 "dtypes"属性または "dtypes"列を削除するかのように、 __delattr__メソッドを混乱させます。

この問題の背景にある建築上の疑問

  1. データフレームは列の集まりですか?
  2. データフレームは行の集合ですか?
  3. 列はデータフレームの属性ですか?

パンダは答えます:

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

TLDR;

del df.column_name実行することはできません。 del df.column_namedel df.column_nameは、この種の認知不調和がユーザに起こらないように再考する必要がある非常に荒々しく成長したアーキテクチャを持っているからです。

Protip:

df.column_nameを使わないでください。それはかなりかもしれませんが、 認識の不協和音を引き起こします

Zen of Pythonの引用符はここに収まります:

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

それを行うには、1つの方法が必要です。

列は時には属性ですが、時にはそうではありません。

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

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

あいまいさに直面して、推測する誘惑を拒む。


常に[]表記を使用することをお勧めします。 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




dataframe