DataFrameの列を削除するときに使用します。
del df['column_name']
そしてこれはうまくいきます。次のものが使えないのはなぜですか?
del df.column_name
df.column_name
として/ Series列にアクセスできるので、これはうまくいくと期待しています。
Pythonの構文上の制限の結果としてdel df.column_name
を単純に機能させることは困難です。 del df[name]
はPythonのカバーの下でdf.__delitem__(name)
に翻訳されます。
パンダでこれをする最も良い方法は drop
を使うことです:
df = df.drop('column_name', 1)
1
は axis の数です(行の場合は0
、列の場合は1
)
df
を再割り当てせずに列を削除するには、次のようにします。
df.drop('column_name', axis=1, inplace=True)
最後に、column label ではなくcolumn number でドロップするには、これを削除してみてください。 1、2、4列目:
df = df.drop(df.columns[[0, 1, 3]], axis=1) # df.columns is zero-based pd.Index
つかいます:
columns = ['Col1', 'Col2', ...]
df.drop(columns, inplace=True, axis=1)
これにより、1つ以上の列がインプレースで削除されます。 inplace=True
は、パンダv0.13で追加されたため、古いバージョンでは動作しません。その場合は、結果を元に戻す必要があります。
df = df.drop(columns, axis=1)
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
ここに提示される実際の質問は、ほとんどの回答で見逃されています。
del df.column_name
を使用できないのはなぜですか?最初に、問題を理解する必要があります。そのためには、 python magic methods に飛び込む必要があります。
Wesが彼の答えで指摘しているように、del df['column']
はpython magic methoddf.__delitem__('column')
にマップされます。これは pandasで実装され、列
ただし、上記のリンクで指摘されている python magic methods :
実際、delは、呼び出される不安定な状況のため、ほとんど使用すべきではありません。注意して使用してください!
del df['column_name']
を使用したり、推奨したりすることはできません。したがって、del df.column_name
を考慮することすらすべきではありません。
ただし、理論的には、 マジックメソッドdel df.column_name
を使用して、__delattr__
をpandasで動作するように実装できます。ただし、これにより、特定の問題、del df['column_name']
実装に既に存在する問題が発生しますが、程度は低くなります。
「dtypes」または「columns」と呼ばれるデータフレームに列を定義するとどうなりますか。
次に、これらの列を削除するとします。
del df.dtypes
は、「dtypes」属性または「dtypes」列を削除する必要があるかのように__delattr__
メソッドを混乱させます。
.ix
、.loc
、または.iloc
メソッドを使用できます。pandasのアーキテクチャは非常に大きく成長しているため、この種の認知的不協和音がユーザーに発生しないようにするために再検討する必要があるため、del df.column_name
を実行できません。
Df.column_nameを使用しないでください。かなりきれいかもしれませんが、認知的不協和音を引き起こします。
列を削除する方法は複数あります。
明白な方法が1つあり、できれば1つだけにする必要があります。
列は属性である場合もありますが、そうでない場合もあります。
特別なケースは、規則を破るほど特別ではありません。
del df.dtypes
はdtypes属性またはdtypes列を削除しますか?
あいまいさに直面して、推測する誘惑を拒否します。
Nice追加は、存在する場合にのみ 列を削除する能力です 。これにより、より多くのユースケースをカバーでき、渡されたラベルから既存の列のみが削除されます。
単純に errors = 'ignore' を追加するだけです。
df.drop(['col_name_1', 'col_name_2', ..., 'col_name_N'], inplace=True, axis=1, errors='ignore')
バージョン0.16.1からあなたができる
df.drop(['column_name'], axis = 1, inplace = True, errors = 'ignore')
常に[]
表記法を使用することをお勧めします。 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
パンダ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)
Pandasバージョン0.21では、drop
およびindex
メソッドのシグニチャと一致するように、columns
およびrename
パラメータの両方を含めるように reindex
メソッドが若干変更されました。
df.drop(columns=['column_a', 'column_c'])
個人的には、列またはインデックスを表すのにaxis
パラメータを使用することをお勧めします。これは、ほとんどすべてのパンダメソッドで使用されている主要なキーワードパラメータだからです。しかし、今、あなたはバージョン0.21でいくつかの追加の選択肢があります。
わずかに効率的な解決策を見つけるための多大な努力。 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つのタイプに分けます。
削除したい列を除いて、残したい列を表すラベルのリスト/配列を作ることから始めます。
df.columns.difference(dlst)
Index(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype='object')
np.setdiff1d(df.columns.values, dlst)
array(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype=object)
df.columns.drop(dlst, errors='ignore')
Index(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype='object')
list(set(df.columns.values.tolist()).difference(dlst))
# does not preserve order
['E', 'D', 'B', 'F', 'G', 'A', 'C']
[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]
それから私達は評価してもいいです
df.loc[:, cols]
df[cols]
df.reindex(columns=cols)
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
スライス用のブール値の配列/リストを作成できます。
~df.columns.isin(dlst)
~np.in1d(df.columns.values, dlst)
[x not in dlst for x in df.columns.values.tolist()]
(df.columns.values[:, None] != dlst).all(1)
ブール値の列
比較のために
bools = [x not in dlst for x in df.columns.values.tolist()]
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')
の実行にかかる時間と相対的です。それは結局のところ、我々はわずかにパフォーマンスを向上させるだけのように思えます。
実際のところ、最善の解決策はハックlist(set(df.columns.values.tolist()).difference(dlst))
のreindex
またはreindex_axis
を使うことです。 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
データフレーム(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)
ドット構文はJavaScriptでは機能しますが、Pythonでは機能しません。
del df['column_name']
del df['column_name']
または del df.column_name
複数のデータフレームから列を削除する
DataFrameのリストから(同じ名前を持つ)列を削除する方法に関する情報を探している場合は、いくつかの方法があります。
1つの方法は、リストを反復処理して各DataFrameをその場で変更することです。
# In-place assignment
for df in df_list:
df.drop('colname', axis=1, inplace=True)
または、
for df in df_list: df.pop('colname')
または、列を(インプレースではなく)ドロップして結果をそのリスト位置に割り当てます。
# Reassigning a copy back to the list
for i, df in enumerate(df_list):
df_list[i] = df.drop('colname', axis=1, inplace=True)
再現可能なコードサンプル
df1 = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
df2 = pd.DataFrame({'A': [4, 5, 7], 'C': ['a', 'b', 'c']})
df1
A B
0 1 4
1 2 5
2 3 6
df2
A C
0 4 a
1 5 b
2 7 c
df_list = [df1, df2]
# Drop column "A"
for df in df_list:
df.drop('A', axis=1, inplace=True)
df1
B
0 4
1 5
2 6
df2
C
0 a
1 b
2 c
for df in df_list: df = df.drop('colname', axis=1)
(つまり、ループ内での再割り当て)が機能しないのはなぜですか?
他の回答で述べたように、df.drop
はデフォルトでコピーを返します。コピーは返され、元のものに変更を加えることなくvariabledf
に再割り当てされます。 inplace=True
引数を使用してdf
をその場で変更するか、コピーをそのリスト要素に明示的に再割り当てする必要があります。
注
変数とオブジェクトの違いを理解することは重要です。変数はオブジェクトへの参照を保持します。変数は、異なるオブジェクトを参照するように再割り当てすることができます。これは、オブジェクト自体を変更することとは関係ありません。このトピックに関する良い入門書として、Ned Batchelderによる この記事を読むことをお勧めします。
これを試して、私はこれが最も簡単な方法だと思います:
drop((['A','B'],axis=1)
Pandas DataFrameの列を削除する別の方法
インプレース削除を探していない場合は、DataFrame(...)
関数を使用して列を指定して新しい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'])
Del/dropで得られるものと同じくらい良い結果が得られます