我有一个列表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
中删除,而不是先添加到列表中。
答案 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
的补充
这比其他人更自我解释。我正在查看从0
到n
的数组,看看它是否在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相同的操作。我最终在0
和1
其他位置定义的每个位置都有一个1
和to_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