如何从Pandas数据框中删除一系列行?

357

我有一个名为df的数据框:

>>> df
                  sales  discount  net_sales    cogs
STK_ID RPT_Date                                     
600141 20060331   2.709       NaN      2.709   2.245
       20060630   6.590       NaN      6.590   5.291
       20060930  10.103       NaN     10.103   7.981
       20061231  15.915       NaN     15.915  12.686
       20070331   3.196       NaN      3.196   2.710
       20070630   7.907       NaN      7.907   6.459

接下来我想要删除特定序列号的行,这些序列号已经列在一个列表中,假设它是[1,2,4], 那么剩下的行为:


                  sales  discount  net_sales    cogs
STK_ID RPT_Date                                     
600141 20060331   2.709       NaN      2.709   2.245
       20061231  15.915       NaN     15.915  12.686
       20070630   7.907       NaN      7.907   6.459

如何或者说哪个函数可以做到这一点?


只是澄清一下,这个问题是关于删除具有特定索引值的行。他们使用[1,2,4]是为了指向删除后剩下的行。下面有做到这点的答案。 - alchemy
15个回答

518

使用 DataFrame.drop 函数,并传递一个索引标签的序列:

In [65]: df
Out[65]: 
       one  two
one      1    4
two      2    3
three    3    2
four     4    1
    
    
In [66]: df.drop(index=[1,3])
Out[66]: 
       one  two
one      1    4
three    3    2

27
除最后一行外,删除数据框中的所有行:df.drop(df.tail(1).index)。+1 - Nasser Al-Wohaibi
28
只有在 df.index.unique() 和 df.index 相同时,这个答案才适用,但这并不是 Pandas DataFrame 的要求。当 df.index 的值不能保证唯一时,有没有人有解决方案? - J Jones
3
这不允许您对索引名称本身进行索引。 - ingrid
67
朋友们,如果你想要讲得清楚明白,请不要在行和列上使用相同的字符串。对于那些已经非常熟悉的人来说没问题,但对于正在学习的人来说会很沮丧。 - gseattle
5
Python新手注意:如果您想删除这些行并将它们保存在同一数据框中(inplace),您还需要添加axis = 0(0 = 行,1 = 列)和inplace = True,如 df.drop(df.index[[1,3]], axis=0, inplace=True). 如果您确切地知道要替换哪些索引(并且也使用了您的从0到n的示例):df.drop(df.index[range(0, n)], axis=0, inplace=True) - mrbTT
显示剩余5条评论

156

78
如果DataFrame非常大,需要删除的行数也很多,那么简单的按索引df.drop(df.index[])方式需要太长时间。在我的情况下,我有一个包含100M行x 3列的浮点数多级索引DataFrame,并且需要从中删除10k行。我找到的最快方法是,相当出乎意料地,take剩余的行。假设indexes_to_drop是要删除的位置索引数组(例如问题中的[1,2,4])。
indexes_to_keep = set(range(df.shape[0])) - set(indexes_to_drop)
df_sliced = df.take(list(indexes_to_keep))

在我的情况下,这个操作花费了20.5秒,而简单的df.drop花费了5分钟27秒并且消耗了很多内存。得到的DataFrame是一样的。


1
难道直接取反掩码比创建一个集合更便宜吗?就像 m = np.ones(len(df), bool); m[indices_to_drop] = False 这样的方式? - Mad Physicist
@MadPhysicist那可能应该更有效率,谢谢! - Dennis Golomazov
处理超过5000万行数据。在Fargate容器上运行速度非常快,约2分钟。 - Ali Berat Çetin

51

我用更简单的方法解决了这个问题 - 仅需2步。

  1. 创建一个包含不需要的行/数据的数据帧。

  2. 使用此不需要的数据帧的索引从原始数据帧中删除行。

例如:
假设你有一个数据帧df,其中包括许多列,包括整数类型的'Age'。现在假设你想删除所有'Age'为负数的行。

df_age_negative = df[ df['Age'] < 0 ] # Step 1
df = df.drop(df_age_negative.index, axis=0) # Step 2
希望这样更简单,有助于您。

4
+1,这是唯一一个告诉你如何删除选择不同于第一列的列的行的答案。 - Alejo Bernardin
2
这就是我一直在寻找的答案。谢谢 Krishnaprasad garu。 - codingbruh
请注意,如果索引包含重复值,则此操作可能会产生不正确的结果。 - Joe

48
你可以将 DataFrame.drop 中的 标签本身 传递(而不是索引标签序列):
In[17]: df
Out[17]: 
            a         b         c         d         e
one  0.456558 -2.536432  0.216279 -1.305855 -0.121635
two -1.015127 -0.445133  1.867681  2.179392  0.518801

In[18]: df.drop('one')
Out[18]: 
            a         b         c         d         e
two -1.015127 -0.445133  1.867681  2.179392  0.518801

这相当于:

In[19]: df.drop(df.index[[0]])
Out[19]: 
            a         b         c         d         e
two -1.015127 -0.445133  1.867681  2.179392  0.518801

1
df.drop(df.index[0]) 也可以。我的意思是,至少在 pandas 0.18.1 中不需要双方括号。 - tagoma

17

如果我想删除一个具有索引值为x的行,我会执行以下操作:

df = df[df.index != x]

如果我想删除多个索引(比如这些索引在列表unwanted_indices中),我会这样做:

desired_indices = [i for i in len(df.index) if i not in unwanted_indices]
desired_df = df.iloc[desired_indices]

这正是我想要的,谢谢!删除除索引X以外的所有行。df = df[df.index == 'x'] - Chris Norris

13

这里有一个具体的例子,我想要展示一下。假设你的某些行中有很多重复的条目。如果你的条目是字符串类型,你可以使用字符串方法轻松地找到所有需要删除的索引。

ind_drop = df[df['column_of_strings'].apply(lambda x: x.startswith('Keyword'))].index

现在,按照它们的索引删除那些行

new_df = df.drop(ind_drop)

8

只使用Index参数来删除行:

df.drop(index = 2, inplace = True)

对于多行:

df.drop(index=[1,3], inplace = True)

3
要删除索引为1、2、4的行,可以使用以下代码:
df[~df.index.isin([1, 2, 4])]

波浪符操作符~可以否定方法isin的结果。另一个选择是删除索引:
df.loc[df.index.drop([1, 2, 4])]

3
根据上述方法确定布尔值的索引,例如:
df[df['column'].isin(values)].index

使用此方法确定索引可能比使用此方法更占用内存。

pd.Index(np.where(df['column'].isin(values))[0])

应用如下。
df.drop(pd.Index(np.where(df['column'].isin(values))[0]), inplace = True)

当处理大型数据框和内存受限时,这种方法非常有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接