2017-10-09 181 views
1

我在熊猫工作,我想跨多个字段应用多个过滤器到数据框。熊猫:多列过滤

我正在处理另一个更复杂的数据框,但我正在简化这个问题。下面是一个简单的数据帧的设置:

dates = pd.date_range('20170101', periods=16) 
rand_df = pd.DataFrame(np.random.randn(16,4), index=dates, columns=list('ABCD')) 

应用一个过滤器,以该数据帧是有据可查的,简单的:

rand_df.loc[lambda df: df['A'] < 0] 

由于拉姆达看起来像一个简单的布尔表达式。很容易做到以下几点。这不起作用,因为它不是一个布尔表达式,而是可调用的。这些不能作为布尔表达式:

rand_df.loc[lambda df: df['A'] < 0 and df[‘B’] < 0] 

--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-31-dfa05ab293f9> in <module>() 
----> 1 rand_df.loc[lambda df: df['A'] < 0 and df['B'] < 0] 

我发现有两种方法可以成功实现这一点。我会将它们添加到潜在的答案中,以便您可以直接对其作出解答。但是,我想征求其他方法,因为我不确定这些方法是否是过滤熊猫数据帧的非常标准的方法。

+0

联合国重复的加速评估。然而它并不像这个那样干净。这个问题有一些多余的背景,例如数据是从CSV读入的。这是一个干净的例子,您可以将代码直接粘贴到您自己的REPL中,提出答案并发布。在很短的时间内,这个问题比重复的候选人有更多的答案。因此,我认为重新开放是有道理的。 –

+0

问题是完全一样的,重复的答案是由熊猫的创建者编写的,所以我认为它是一个安全的选择,那是过滤数据框的最佳方式。 – DJK

+0

谢谢。谦虚地指出,我应该特别考虑Wes McKinney回答的熊猫问题。 –

回答

2

这里有一个办法,“链”使用 '禄' 操作:

rand_df.loc[lambda df: df['A'] < 0].loc[lambda df: df['B'] < 0] 
3
rand_df[(rand_df.A < 0) & (rand_df.B <0)] 
5
In [3]: rand_df.query("A < 0 and B < 0") 
Out[3]: 
        A   B   C   D 
2017-01-02 -0.701682 -1.224531 -0.273323 -1.091705 
2017-01-05 -1.262971 -0.531959 -0.997451 -0.070095 
2017-01-06 -0.065729 -1.427199 1.202082 0.136657 
2017-01-08 -1.445050 -0.367112 -2.617743 0.496396 
2017-01-12 -1.273692 -0.456254 -0.668510 -0.125507 

或:

In [6]: rand_df[rand_df[['A','B']].lt(0).all(1)] 
Out[6]: 
        A   B   C   D 
2017-01-02 -0.701682 -1.224531 -0.273323 -1.091705 
2017-01-05 -1.262971 -0.531959 -0.997451 -0.070095 
2017-01-06 -0.065729 -1.427199 1.202082 0.136657 
2017-01-08 -1.445050 -0.367112 -2.617743 0.496396 
2017-01-12 -1.273692 -0.456254 -0.668510 -0.125507 

PS你会发现很多的例子在the Pandas docs

1

这里是一种方法,其中包括编写一个方法来完成过滤。我相信一些过滤器将会非常复杂或复杂,以至于这种方法是最好的方法(这种情况并不复杂)。另外,当我使用熊猫并且写一个“for”循环时,我感觉像是我做错了。

def lt_zero_ab(df): 
    result = [] 
    for index, row in df.iterrows(): 
     if row['A'] <0 and row['B'] <0: 
      result.append(index) 
    return result 
rand_df.loc[lt_zero_ab] 
4

要使用lambda,请不要传递整列。对于此已标记为重复不回答我的问题的问题:

rand_df.loc[lambda x: (x.A < 0) & (x.B < 0)] 
# Or 
# rand_df[lambda x: (x.A < 0) & (x.B < 0)] 

        A   B   C   D 
2017-01-12 -0.460918 -1.001184 -0.796981 0.328535 
2017-01-14 -0.146846 -1.088095 -1.055271 -0.778120 

您可以通过使用布尔numpy的阵列

c1 = rand_df.A.values > 0 
c2 = rand_df.B.values > 0 
rand_df[c1 & c2] 

        A   B   C   D 
2017-01-12 -0.460918 -1.001184 -0.796981 0.328535 
2017-01-14 -0.146846 -1.088095 -1.055271 -0.778120