在 Pandas 数据框中基于多个条件删除行。

26

当满足一些条件时,我想要删除行:

下面展示了一个示例数据框:

        one       two     three      four
0 -0.225730 -1.376075  0.187749  0.763307
1  0.031392  0.752496 -1.504769 -1.247581
2 -0.442992 -0.323782 -0.710859 -0.502574
3 -0.948055 -0.224910 -1.337001  3.328741
4  1.879985 -0.968238  1.229118 -1.044477
5  0.440025 -0.809856 -0.336522  0.787792
6  1.499040  0.195022  0.387194  0.952725
7 -0.923592 -1.394025 -0.623201 -0.738013
8 -1.775043 -1.279997  0.194206 -1.176260
9 -0.602815  1.183396 -2.712422 -0.377118

我想根据以下条件删除行:

列“one”、“two”或“three”的值大于0;并且列“four”的值小于0的行应该被删除。

然后我尝试按照以下方式实现:

df = df[df.one > 0 or df.two > 0 or df.three > 0 and df.four < 1]

然而,它会导致以下错误信息:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

有人可以帮我解决如何基于多个条件进行删除的问题吗?

2个回答

52

对于我来说不是完全清楚的原因pandas 使用按位逻辑运算符 |& 的方式很好,但不使用布尔逻辑运算符 orand

请尝试以下方法:

df = df[(df.one > 0) | (df.two > 0) | (df.three > 0) & (df.four < 1)]

6
你想要 df = df[((df.one > 0) | (df.two > 0) | (df.three > 0)) & (df.four < 1)],原因是比较数组是不明确的,因为可能有多个匹配项,请参考此链接:https://dev59.com/Gmkw5IYBdhLWcg3wMHyn。 - EdChum
1
哦,糟糕,没看到末尾的and。已编辑。 - Brionius
1
@Brionius:基本上是因为orand不能通过类来自定义它们的行为。它们的运作方式基于bool(the_object)的结果,就是这样。 - DSM
要删除包含20个可能的子键之一的字符串的任何行,请查看此处 - zelusp

0

drop 可以用于删除行

最明显的方法是根据条件构建布尔掩码,通过它筛选索引以获取要删除的索引数组,并使用 drop() 删除这些索引。如果条件是:

值为 col 'one'、'two' 或 'three' 大于 0;且值为 col 'four' 小于 0 的行应该被删除。

那么可以使用以下代码:

msk = (df['one'].gt(0) | df['two'].gt(0) | df['three'].gt(0)) & df['four'].lt(0)
idx_to_drop = df.index[msk]
df1 = df.drop(idx_to_drop)

条件的第一部分,即col 'one','two'或'three'大于0可以使用.any(axis=1)更简洁地书写:
msk = df[['one', 'two', 'three']].gt(0).any(axis=1) & df['four'].lt(0)

保留要删除的行的补集

删除/移除/丢弃行是保留行的相反操作。因此,完成此任务的另一种方法是对于要删除的行的布尔掩码取反(~),并通过它来过滤数据框。

msk = df[['one', 'two', 'three']].gt(0).any(axis=1) & df['four'].lt(0)
df1 = df[~msk]

query() 保留行

pd.DataFrame.query() 是一个非常易读的 API,用于过滤要保留的行。它还“理解”and/or等逻辑运算符。因此,以下操作是有效的。

# negate the condition to drop
df1 = df.query("not ((one > 0 or two > 0 or three > 0) and four < 0)")

# the same condition transformed using de Morgan's laws
df1 = df.query("one <= 0 and two <= 0 and three <= 0 or four >= 0")

以上所有操作都执行以下转换:

result


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接