尝试从Pandas Dataframe中删除多行但删除的行数多于预期

时间:2017-08-15 17:15:35

标签: python pandas dataframe

我有一个列表to_delete,我想要从我的两个Pandas Dataframes中删除行索引,df1& DF2。它们都有500行。 to_delete有50个条目。 我跑这个:

df1.drop(df1.index[to_delete], inplace=True)
df2.drop(df2.index[to_delete], inplace=True) 

但是这导致df1和df2各有250行。它从每个中删除250行,而不是我想要它的50个特定行...

to_delete按降序排列。

完整的方法:

def method(results):
    #results is a 500 x 1 matrix of 1's and -1s
    global df1, df2
    deletions = []
    for i in xrange(len(results)-1, -1, -1):
        if results[i] == -1:
        deletions.append(i)
    df1.drop(df1.index[deletions], inplace=True)
    df2.drop(df2.index[deletions], inplace=True)

关于我做错了什么建议?

(我也尝试使用.iloc代替.index并在if statement中删除,而不是先添加到列表中。

1 个答案:

答案 0 :(得分:2)

您的索引值不是唯一的,当您使用drop时,它会删除具有这些索引值的所有行。 to_delete可能长度为50,但有250行具有这些特定的索引值。

考虑示例

df = pd.DataFrame(dict(A=range(10)), [0, 1, 2, 3, 4] * 2)

df

   A
0  0
1  1
2  2
3  3
4  4
0  5
1  6
2  7
3  8
4  9

假设您要删除第一行,第三行和第四行。

to_del = [0, 2, 3]

使用您的方法

df.drop(df.index[to_del])

   A
1  1
4  4
1  6
4  9

哪个是问题

选项1
使用np.in1d查找to_del的补充 这比其他人更自我解释。我正在查看从0n的数组,看看它是否在to_del中。结果将是一个与df长度相同的布尔数组。我使用~来获取否定并使用它来切片数据帧。

df[~np.in1d(np.arange(len(df)), to_del)]

   A
1  1
4  4
0  5
1  6
2  7
3  8
4  9

选项2
使用np.bincount查找to_del的补充 这通过计算to_del中定义的位置来完成与选项1相同的操作。我最终在01其他位置定义的每个位置都有一个1to_del数组0。我想保留0 s,所以我通过查找它等于0的位置来创建一个布尔数组。然后我用它来分割数据帧。

df[np.bincount(to_del, minlength=len(df)) == 0]

   A
1  1
4  4
0  5
1  6
2  7
3  8
4  9

选项3
使用np.setdiff1d查找位置
这使用set逻辑来查找完整的位置数组和我想要删除的位置之间的差异。然后我使用iloc进行选择。

df.iloc[np.setdiff1d(np.arange(len(df)), to_del)]

   A
1  1
4  4
0  5
1  6
2  7
3  8
4  9