如何从熊猫数据框中删除行列表?


257

我有一个数据框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]的使用是指向删除后剩余的行。下面有答案可以做到这一点。
炼金术

Answers:


386

使用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(df.index[[1,3]])
Out[66]: 
       one  two
one      1    4
three    3    2

18
+1此外,删除最后一行df.drop(df.tail(1).index)
Nasser Al-Wohaibi 2014年

15
仅当df.index.unique()与df.index相同时才可以使用此答案,而这对于Pandas DataFrame而言不是必需的。当df.index值不能保证唯一时,有人解决方案吗?
J琼斯

2
这不允许您对索引名称本身进行索引
2016年

45
在示例中,如果您想清楚一点,请不要使用相同的字符串作为行和列。对于已经真正了解他们的知识的人来说,这很好。那些试图学习的人感到沮丧。
gseattle

2
python的新手:请注意,如果要删除这些行并将它们保存在同一数据帧中(就地),则还需要添加axis=0(0 =行,1 =列),inplace=Truedf.drop(df.index[[1,3]], axis=0, inplace=True)。@mezzanaccio,如果您明确知道要替换的索引(也使用0到n的示例):df.drop(df.index[range(0, n)], axis=0, inplace=True)
mrbTT


47

如果DataFrame很大,并且要删除的行数也很大,那么按索引df.drop(df.index[])进行简单的删除将花费太多时间。

在我的情况下,我有一个带的浮点数的多索引DataFrame 100M rows x 3 cols,我需要从中删除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.5s,而简单的df.drop花费5min 27s了很多内存。所得的DataFrame是相同的。


43

您还可以传递给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])也可以。我的意思是,不需要双方括号(至少熊猫为0.18.1)
塔戈马

23

我以一种简单的方式解决了这一问题-仅需两个步骤。

步骤1:首先形成包含不需要的行/数据的数据框。

步骤2:使用此不需要的数据框的索引从原始数据框删除行。

例:

假设您有一个数据框df,其中包括“ Age”的整数列,该列是整数。现在假设您要删除所有以“年龄”为负数的行。

步骤1:df_age_negative = df [df ['Age'] <0]

步骤2:df = df.drop(df_age_negative.index,axis = 0)

希望这会更简单并且对您有所帮助。


1
+1,这是唯一告诉您如何删除选择与第一列不同的列的行的答案。
Alejo Bernardin

10

如果要删除具有index的行x,我将执行以下操作:

df = df[df.index != x]

如果我想删除多个索引(例如,这些索引在list中unwanted_indices),则可以执行以下操作:

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

6

我想展示一些具体的例子。假设您在某些行中有许多重复的条目。如果您有字符串条目,则可以轻松地使用字符串方法来查找所有要删除的索引。

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

现在使用它们的索引删除这些行

new_df = df.drop(ind_drop)

3

在对@ theodros-zelleke的答案的评论中,@ j-jones询问了如果索引不是唯一的怎么办。我不得不处理这种情况。我要做的是在我叫drop()la 之前重命名索引中的重复项:

dropped_indexes = <determine-indexes-to-drop>
df.index = rename_duplicates(df.index)
df.drop(df.index[dropped_indexes], inplace=True)

rename_duplicates()我定义的函数在哪里,它通过了index元素并重命名了重复项。我使用了与pd.read_csv()在列上相同的重命名模式,即,"%s.%d" % (name, count)其中name行的名称和count它以前发生过的次数。


1

如上所述,从布尔值确定索引,例如

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)

当处理大数据帧和有限的内存时,此方法很有用。


0

仅使用索引arg删除行:

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

对于多行:

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

0

考虑一个示例数据框

df =     
index    column1
0           00
1           10
2           20
3           30

我们要删除第二和第三索引行。

方法1:

df = df.drop(df.index[2,3])
 or 
df.drop(df.index[2,3],inplace=True)
print(df)

df =     
index    column1
0           00
3           30

 #This approach removes the rows as we wanted but the index remains unordered

方法2

df.drop(df.index[2,3],inplace=True,ignore_index=True)
print(df)
df =     
index    column1
0           00
1           30
#This approach removes the rows as we wanted and resets the index. 
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.