2017-10-09 242 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