如何从Pandas数据帧中删除行列表?

时间:2013-02-02 12:03:46

标签: python pandas

我有一个数据帧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

如何或以何种方式可以做到这一点?

14 个答案:

答案 0 :(得分:329)

使用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

答案 1 :(得分:94)

请注意,使用" inplace"当你想要进行下线时命令。

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

因为您的原始问题没有返回任何内容,所以应该使用此命令。 http://pandas.pydata.org/pandas-docs/version/0.17.0/generated/pandas.DataFrame.drop.html

答案 2 :(得分:39)

您还可以传递给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

答案 3 :(得分:34)

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

就我而言,我有一个带有100M rows x 3 cols的浮点数的多索引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.5s,而简单的df.drop花费了5min 27s并消耗了大量内存。生成的DataFrame是相同的。

答案 4 :(得分:15)

我以更简单的方式解决了这个问题 - 只需两步。

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

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

示例:

假设您有一个数据帧df,其中包含'Age'这一整数列。现在让我们假设您要删除所有行,其中'Age'为负数。

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

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

希望这更简单并帮助你。

答案 5 :(得分:9)

如果我想删除一个让我们说索引为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]

答案 6 :(得分: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()是我定义的函数,它遍历了索引元素并重命名了重复项。我使用与pd.read_csv()在列上使用相同的重命名模式,即"%s.%d" % (name, count),其中name是行的名称,count是以前发生过的次数

答案 7 :(得分:2)

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

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

现在使用索引删除这些行

new_df = df.drop(ind_drop)

答案 8 :(得分:1)

查看以下数据框df

df

   column1  column2  column3
0        1       11       21
1        2       12       22
2        3       13       23
3        4       14       24
4        5       15       25
5        6       16       26
6        7       17       27
7        8       18       28
8        9       19       29
9       10       20       30

让所有列中第一个为奇数的行都丢弃

在column1中创建所有元素的列表,并仅保留偶数个元素(您不想删除的元素)

keep_elements = [x for x in df.column1 if x%2==0]

列1中所有值为[2, 4, 6, 8, 10]的行将保留或不删除。

df.set_index('column1',inplace = True)
df.drop(df.index.difference(keep_elements),axis=0,inplace=True)
df.reset_index(inplace=True)

我们将column1作为索引,并删除所有不需要的行。然后我们重新设置索引。 df

   column1  column2  column3
0        2       12       22
1        4       14       24
2        6       16       26
3        8       18       28
4       10       20       30

答案 9 :(得分:0)

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

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)

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

答案 10 :(得分:0)

仅使用索引arg删除行:-

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

对于多行:-

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

答案 11 :(得分: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. 

答案 12 :(得分:0)

要删除索引为 1、2、4 的行,您可以使用:

df[~df.index.isin([1, 2, 4])]

波浪号运算符 ~ 否定方法 isin 的结果。另一种选择是删除索引:

df.loc[df.index.drop([1, 2, 4])]

答案 13 :(得分:0)

正如 Dennis Golomazov's answer 建议的那样,使用 drop 删除行。您可以选择保留行。假设您有一个名为 indices_to_drop 的要删除的行索引列表。您可以将其转换为掩码,如下所示:

mask = np.ones(len(df), bool)
mask[indices_to_drop] = False

你可以直接使用这个索引:

df_new = df.iloc[mask]

这个方法的好处是 mask 可以来自任何来源:它可以是涉及许多列的条件,也可以是其他东西。

真正好的一点是,你真的根本不需要原始 DataFrame 的索引,所以索引是否唯一并不重要。

缺点当然是你不能用这种方法就地放置。