如何根据多列中的数据从Pandas数据帧中删除行?

时间:2015-05-21 18:17:32

标签: python pandas

我知道如何根据this stack overflow question,中的简单条件删除行,但是,我需要使用更复杂的条件删除行。

我的情况:我有数据行,其中每行有四列包含数字代码。我需要删除所有没有至少一个前导数字少于5的代码的行。我目前有一个函数,我可以使用dataframe.apply创建一个新列,'keep',和如果它是要保留的行,则用1填充它。然后,我使用该简单的保留列进行第二次传递,以删除不需要的行。我正在寻找的是一种方法,只需一次通过,而无需创建新列。

示例数据:

   a | b | c | d
0 145|567|999|876
1 999|876|543|543

在那个数据中,我想保留第一行,因为在'a'列中,前导数字小于5.第二行没有前导数字小于5的列,因此需要删除该行

1 个答案:

答案 0 :(得分:4)

这应该有效:

In [31]:
df[(df.apply(lambda x: x.str[0].astype(int))).lt(5).any(axis=1)]

Out[31]:
     a    b    c    d
0  145  567  999  876

所以基本上这会使用向量化str方法获取每列的第一个字符,我们将其转换为int,然后我们调用lt,它小于行方式以生成布尔值df然后,我们在df行上调用any以在索引上生成一个布尔掩码,用于掩盖df。所以打破了上面的内容:

In [34]:
df.apply(lambda x: x.str[0].astype(int))

Out[34]:
   a  b  c  d
0  1  5  9  8
1  9  8  5  5

In [35]:    
df.apply(lambda x: x.str[0].astype(int)).lt(5)

Out[35]:
       a      b      c      d
0   True  False  False  False
1  False  False  False  False

In [37]:    
df.apply(lambda x: x.str[0].astype(int)).lt(5).any(axis=1)

Out[37]:
0     True
1    False
dtype: bool

修改

要处理NaN值,请添加对dropna的调用:

In [39]:
t="""a,b,c,d
0,145,567,999,876
1,999,876,543,543
2,,324,344"""
df = pd.read_csv(io.StringIO(t),dtype=str)
df

Out[39]:
     a    b    c    d
0  145  567  999  876
1  999  876  543  543
2  NaN  324  344  NaN

In [44]:
df[(df.apply(lambda x: x.dropna().str[0].astype(int))).lt(5,axis=0).any(axis=1)]

Out[44]:
     a    b    c    d
0  145  567  999  876
2  NaN  324  344  NaN