这是一个捕捉我的问题的玩具示例。有什么帮助吗?谢谢!
d = {'a': [1,1,1,2,2,2,3,3,3],
'b': [1,2,3,1,2,3,1,2,3]}
df = pd.DataFrame(d)
针对此结果:
我想删除(a,b)=(1,3)或(2,1)的两行。
result = pd.DataFrame({'a': [1,1,2,2,3,3,3],
'b': [1,2,2,3,1,2,3]})
实际上,我会有一个排除列表,该列表会随时间更新: 排除= [[1,3],[2,1],[3,4],........]
答案 0 :(得分:3)
当我们应该能够挥动双手时,这就像发射一门大炮,但是:
df = pd.DataFrame({'a': [1,1,1,1,2,2,2,3,3,3],
'b': [1,1,2,3,1,2,3,1,2,3]})
excl = [[1, 3], [2, 1]]
keep = df.merge(pd.DataFrame(excl, columns=['a','b']),
how='left', indicator=True)._merge == 'left_only'
给我
In [91]: df.loc[keep]
Out[91]:
a b
0 1 1
1 1 1
2 1 2
5 2 2
6 2 3
7 3 1
8 3 2
9 3 3
(请注意,出于理智目的,我添加了重复的1,1行。)
疯狂的方法2 :(有效地)使用分类编码:
codes = pd.concat([df, edf], sort=False).groupby(["a","b"]).ngroup()
keep = ~codes.iloc[:len(df)].isin(codes.iloc[len(df):])
df = df.loc[keep]
答案 1 :(得分:2)
将“禁止”行的列表转换为列名称与原始数据框不同的数据框:
to_drop = pd.DataFrame(excl, columns=('c','d')) # Different column names!
合并两个数据框。将有NaN
个不匹配的地方:
combined = df.merge(to_drop, how='outer', left_on=['a','b'], right_on=['c','d'])
最初从第二个数据帧中取出任何列,找出NaN
在哪里,并使用它们的索引从第一个数据帧中提取有效行:
df[combined.isnull()['d']]
# a b
#0 1 1
#1 1 2
#4 2 2
#5 2 3
#6 3 1
#7 3 2
#8 3 3
您可能会看到警告:
UserWarning:布尔系列键将被重新索引以匹配DataFrame索引。
您现在可以忽略它。
答案 2 :(得分:2)
另一种棘手的解决方案:
df = pd.DataFrame({'a': [1,1,1,2,2,2,3,3,3],
'b': [1,2,3,1,2,3,1,2,3]})
to_drop = pd.DataFrame({'a': [1, 2], 'b': [3, 1]})
result = df.merge(to_drop, on=['a', 'b'], how='outer', indicator=True)
result = result[result['_merge'] == 'left_only'].drop('_merge', axis=1)
结果:
a b
0 1 1
1 1 2
4 2 2
5 2 3
6 3 1
7 3 2
8 3 3
答案 3 :(得分:2)
将tuple
与isin
一起使用
df[~df.apply(tuple,1).isin([(1,3),(2,1)])]
Out[568]:
a b
0 1 1
1 1 2
4 2 2
5 2 3
6 3 1
7 3 2
8 3 3
答案 4 :(得分:-1)
尝试:
result = df.loc[(df['a'] == 1 & df['b'] == 3) | (df['a'] == 2 & df['b'] == 1)]