当删除一个DataFrame中的列时,我使用。
del df['column_name']
这样做效果很好。为什么我不能使用下面的方法呢?
del df.column_name
*因为你可以以df.column_name的形式访问列/系列,我希望这个方法能起作用。
df.column_name
在pandas中最好的方法是使用drop。
drop
df = df.drop('column_name', 1)
其中1是轴号(0代表行,1代表列。
1
0
要删除该列而不需要重新分配df,你可以这样做。
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
正如你所猜测的,正确的语法是
由于Python的语法限制,很难使del df.column_name发挥作用。del df[name]被Python翻译成df.__delitem__(name)。
del df[name]
df.__delitem__(name)
使用。
columns = ['Col1', 'Col2', ...] df.drop(columns, inplace=True, axis=1)
这将在原地删除一列或多列。 请注意,"inplace=True "是在pandas v0.13中添加的,在旧版本中不起作用。 在这种情况下,你必须将结果赋值回去。
df = df.drop(columns, axis=1)
删除第一、二、四栏。
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。
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。
three = df.pop('three')
two A 2 B 5 C 8
实际的问题是,这里的大多数答案都忽略了。
首先我们需要了解这个问题,这就需要我们深入研究[python神奇方法][1]。
正如Wes在答案中指出的那样,del df['column']映射到python 神奇方法df.__delitem__('column'),它是[在pandas中实现的丢弃列][2] 。
del df['column']
df.__delitem__('column')
不过,正如上面关于[python神奇方法][1]的链接中指出的。
事实上,del几乎不应该被使用,因为它的调用环境很不稳定。 谨慎使用它!
你可以说del df['column_name']不应该使用或鼓励使用,因此del df.column_name甚至不应该被考虑。
del df['column_name']
然而,理论上,del df.column_name可以用[神奇的方法__delattr__][3]实现在pandas中工作。 然而,这确实引入了一些问题,这些问题是del df['column_name']实现中已经存在的,但程度较轻。
__delattr__
如果我在一个名为"dtypes"的数据框架中定义了一个列。 或"columns"的数据框架中定义一个列。
那么假设我想删除这些列。
del df.dtypes会让__delattr__方法感到困惑,好像它应该删除"dtypes" 属性,还是删除"dtypes" 列。
del df.dtypes
数据框是行的集合吗?
一个列是一个数据框架的*属性吗?
没有,但如果你想这样,你可以使用.ix、.loc或.iloc方法。
.ix
.loc
.iloc
也许,你想读数据吗? 那就是,除非的属性名已经被属于数据框架的另一个属性所占用。 4.你想修改*数据吗? 那么不。
你不能做 "del df.column_name",因为pandas有一个相当野蛮生长的架构,需要重新考虑,以避免这种认知失调发生在用户身上。
不要使用df.column_name,它可能很好看,但它会导致认知失调。
有多种方法可以删除一列。 >.有多种方法删除一列。 应该有一种--最好只有一种--显而易见的方法来做。
列有时是属性,但有时不是。
。 特殊情况并没有特殊到破坏规则的程度。
del df.dtypes是删除dtypes属性还是dtypes列?
del df.dtypes是删除dtypes属性还是dtypes列? 面对歧义,拒绝猜测的诱惑。
[1]: https://rszalski.github.io/magicmethods/ [2]: https://github.com/pydata/pandas/blob/c6110e25b3eceb2f25022c2aa9ccea03c0b8b359/pandas/core/generic.py#L1580 [3]: https://rszalski.github.io/magicmethods/#access
一个很好的补充是能够只在列存在的情况下丢弃列。 这样你就可以覆盖更多的用例,而且它只会从传递给它的标签中删除现有的列。
简单地添加errors='ignore',例如..:
df.drop(['col_name_1', 'col_name_2', ..., 'col_name_N'], inplace=True, axis=1, errors='ignore')
[1]: http://pandas.pydata.org/pandas-docs/version/0.17.0/generated/pandas.DataFrame.drop.html
从0.16.1版本开始,你可以做的是
df.drop(['column_name'], axis = 1, inplace = True, errors = 'ignore')
始终使用"[]"符号是一个好的做法。原因之一是,属性符号(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 "", line 1 df.1 ^ SyntaxError: invalid syntax
在pandas 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方法的签名。
index
columns
rename
reindex
df.drop(columns=['column_a', 'column_c'])
就我个人而言,我更喜欢使用axis参数来表示列或索引,因为它是几乎所有pandas方法中最主要的关键字参数。 但是,现在你在0.21版本中增加了一些选择。
axis
为找到一个稍微有效的解决方案付出了很多努力。 在牺牲df.drop(dlst, 1, errors='ignore')的简单性的同时,很难证明增加了复杂性。
df.drop(dlst, 1, errors='ignore')
df.reindex_axis(np.setdiff1d(df.columns.values, dlst), 1)
序言。 删除一列与选择其他列在语义上是一样的。 我'会展示一些额外的方法来考虑。
我'我还将重点介绍一次删除多个列的一般解决方案,并允许尝试删除不存在的列。
使用这些解决方案是通用的,对于简单的情况也会有效。
设置 考虑到pd.DataFrame``df和列表删除dlst。
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
。
由于我把删除一列等同于选择其他列,所以我'将其分为两种类型。
1、标签选择 2. 布尔选择
我们先制造代表我们要保留的列和没有我们要删除的列的标签列表/数组。
df.columns.difference(dlst)
Index(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype='对象')
np.setdiff1d(df.columns.value, dlst)
array(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype=object)
df.columns.drop(dlst, errors='ignore')
list(set(df.column.values.tolist()).difference(dlst))
'E','D','B','F','G','A','C'】。
[x for x in df.column.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.reindex(columns=cols)。
df.reindex(columns=cols)
df.reindex_axis(cols, 1)。
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
我们可以构造一个数组/booleans列表来进行分片。
~df.columns.isin(dlst)
~np.in1d(df.columns.value, dlst)。
~np.in1d(df.columns.value, dlst)
[x not in dlst for x in df.columns.values.tolist()]。
[x not in dlst for x in df.columns.values.tolist()]
(df.columns.values[:, None] != dlst).all(1)。
(df.columns.values[:, None] != dlst).all(1)
来自布尔值的列 为了便于比较
bools = [x not in dlst for x in df.columns.values.tolist()]
df.loc[: bools]
生锈的时间
职能
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')所需要的时间而言的。 看来经过这么多的努力,我们只能适度提高性能。
[![在此输入图片描述][1]][1] 。
事实上,最好的解决方案是使用reindex或reindex_axis上的黑客list(set(df.column.values.tolist()).difference(dlst))。 紧随其后,比 "drop "还略胜一筹的是np.setdiff1d。
reindex_axis
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
[1]: https://i.stack.imgur.com/208z6.png
点阵语法在JavaScript中可以使用,但在Python中就不行了。
删除Pandas DataFrame中某一列的另一种方式__。
如果你'不是在寻找In-Place删除,那么你可以通过使用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得到的一样好。
在pandas中最好的方法是使用
drop
。其中
1
是轴号(0
代表行,1
代表列。要删除该列而不需要重新分配
df
,你可以这样做。最后,要想通过列数字而不是列标签进行删除,可以尝试这样删除,例如,第1、2和4列。
正如你所猜测的,正确的语法是
由于Python的语法限制,很难使
del df.column_name
发挥作用。del df[name]
被Python翻译成df.__delitem__(name)
。使用。
这将在原地删除一列或多列。 请注意,"inplace=True "是在pandas v0.13中添加的,在旧版本中不起作用。 在这种情况下,你必须将结果赋值回去。
滴滴指数
删除第一、二、四栏。
删除第一栏。
有一个可选的参数 "inplace",以便使原来的 可以在不创建副本的情况下修改数据。
弹出
栏目选择、增加、删除
删除 "column-name "列。
例子:
print df
。df.drop(df.columns[[0]], axis=1, inplace=True)
。print df
。three = df.pop('three')
。print df
。实际的问题是,这里的大多数答案都忽略了。
Why can't I use
del df.column_name
?首先我们需要了解这个问题,这就需要我们深入研究[python神奇方法][1]。
正如Wes在答案中指出的那样,
del df['column']
映射到python 神奇方法df.__delitem__('column')
,它是[在pandas中实现的丢弃列][2] 。不过,正如上面关于[python神奇方法][1]的链接中指出的。
你可以说
del df['column_name']
不应该使用或鼓励使用,因此del df.column_name
甚至不应该被考虑。然而,理论上,
del df.column_name
可以用[神奇的方法__delattr__
][3]实现在pandas中工作。 然而,这确实引入了一些问题,这些问题是del df['column_name']
实现中已经存在的,但程度较轻。示例问题
如果我在一个名为"dtypes"的数据框架中定义了一个列。 或"columns"的数据框架中定义一个列。
那么假设我想删除这些列。
del df.dtypes
会让__delattr__
方法感到困惑,好像它应该删除"dtypes" 属性,还是删除"dtypes" 列。这个问题背后的架构问题。
数据框是行的集合吗?
一个列是一个数据框架的*属性吗?
Pandas的答案。
没有,但如果你想这样,你可以使用
.ix
、.loc
或.iloc
方法。也许,你想读数据吗? 那就是,除非的属性名已经被属于数据框架的另一个属性所占用。 4.你想修改*数据吗? 那么不。
TLDR。
你不能做 "del df.column_name",因为pandas有一个相当野蛮生长的架构,需要重新考虑,以避免这种认知失调发生在用户身上。
Protip:
不要使用df.column_name,它可能很好看,但它会导致认知失调。
Python的名言,适合放在这里。
有多种方法可以删除一列。 >.有多种方法删除一列。 应该有一种--最好只有一种--显而易见的方法来做。
列有时是属性,但有时不是。
del df.dtypes
是删除dtypes属性还是dtypes列?[1]: https://rszalski.github.io/magicmethods/ [2]: https://github.com/pydata/pandas/blob/c6110e25b3eceb2f25022c2aa9ccea03c0b8b359/pandas/core/generic.py#L1580 [3]: https://rszalski.github.io/magicmethods/#access
一个很好的补充是能够只在列存在的情况下丢弃列。 这样你就可以覆盖更多的用例,而且它只会从传递给它的标签中删除现有的列。
简单地添加errors='ignore',例如..:
[1]: http://pandas.pydata.org/pandas-docs/version/0.17.0/generated/pandas.DataFrame.drop.html
从0.16.1版本开始,你可以做的是
始终使用"[]"符号是一个好的做法。原因之一是,属性符号(
df.column_name
)对数字索引不起作用。在pandas 0.16.1+中,只有当列存在时,你才能按照@eiTanLaVi发布的解决方案删除列。 在该版本之前,你可以通过条件列表理解来实现同样的结果。
Pandas 0.21+答案
Pandas 0.21版对
drop
方法稍作修改,加入了index
和columns
参数,以匹配rename
和reindex
方法的签名。就我个人而言,我更喜欢使用
axis
参数来表示列或索引,因为它是几乎所有pandas方法中最主要的关键字参数。 但是,现在你在0.21版本中增加了一些选择。TL;DR
为找到一个稍微有效的解决方案付出了很多努力。 在牺牲
df.drop(dlst, 1, errors='ignore')
的简单性的同时,很难证明增加了复杂性。序言。 删除一列与选择其他列在语义上是一样的。 我'会展示一些额外的方法来考虑。
我'我还将重点介绍一次删除多个列的一般解决方案,并允许尝试删除不存在的列。
使用这些解决方案是通用的,对于简单的情况也会有效。
设置 考虑到
pd.DataFrame``df
和列表删除dlst
。结果应该是这样的:
。
由于我把删除一列等同于选择其他列,所以我'将其分为两种类型。
1、标签选择 2. 布尔选择
标签选择
我们先制造代表我们要保留的列和没有我们要删除的列的标签列表/数组。
df.columns.difference(dlst)
。Index(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype='对象')
np.setdiff1d(df.columns.value, 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='对象')
list(set(df.column.values.tolist()).difference(dlst))
。不维护秩序
'E','D','B','F','G','A','C'】。
[x for x in df.column.values.tolist() if x not in dlst]
。['A';, 'B';, 'C';, 'D';, 'E';, 'F';, 'G';]
来自标签的栏目 为了比较选择过程,假设。
那么我们可以评估
df.loc[:,cols]
。df.reindex(columns=cols)
。df.reindex_axis(cols, 1)
。这一切的评价是:
布尔型切片
我们可以构造一个数组/booleans列表来进行分片。
~df.columns.isin(dlst)
。~np.in1d(df.columns.value, dlst)
。[x not in dlst for x in df.columns.values.tolist()]
。(df.columns.values[:, None] != dlst).all(1)
。来自布尔值的列 为了便于比较
df.loc[: bools]
。这一切的评价是:
生锈的时间
职能
测试
这是相对于运行
df.drop(dlst, 1, errors='ignore')
所需要的时间而言的。 看来经过这么多的努力,我们只能适度提高性能。[![在此输入图片描述][1]][1] 。
事实上,最好的解决方案是使用
reindex
或reindex_axis
上的黑客list(set(df.column.values.tolist()).difference(dlst))
。 紧随其后,比 "drop "还略胜一筹的是np.setdiff1d
。[1]: https://i.stack.imgur.com/208z6.png
点阵语法在JavaScript中可以使用,但在Python中就不行了。
del df['column_name']
del df['column_name']
del df['column_name']
或del df.column_name
。删除Pandas DataFrame中某一列的另一种方式__。
如果你'不是在寻找In-Place删除,那么你可以通过使用
DataFrame(...)
函数指定列来创建一个新的DataFrame,如创建一个新的DataFrame作为
你得到的结果和你用del/drop得到的一样好。