2017-08-28 145 views
3

我想篩選使用閾值的熊貓數據幀的三列動態濾波大熊貓據幀

import pandas as pd 
df = pd.DataFrame({"A" : [6, 2, 10, -5, 3], 
        "B" : [2, 5, 3, 2, 6], 
        "C" : [-5, 2, 1, 8, 2]}) 
df = df.loc[(df.A > 0) & (df.B > 2) & (df.C > -1)].reset_index(drop = True) 

df 
    A B C 
0 2 5 2 
1 10 3 1 
2 3 6 2 

不過,我想這樣做一個函數內,其中列及其臨界值的名稱將被賦予給我一本字典。這是我的第一次嘗試,工作正常。從本質上講,我把過濾器內部cond變量,只要運行它:

df = pd.DataFrame({"A" : [6, 2, 10, -5, 3], 
        "B" : [2, 5, 3, 2, 6], 
        "C" : [-5, 2, 1, 8, 2]}) 
limits_dic = {"A" : 0, "B" : 2, "C" : -1} 
cond = "df = df.loc[" 
for key in limits_dic.keys(): 
    cond += "(df." + key + " > " + str(limits_dic[key])+ ") & " 
cond = cond[:-2] + "].reset_index(drop = True)" 
exec(cond) 
df 
    A B C 
0 2 5 2 
1 10 3 1 
2 3 6 2 

現在,終於我把一切都在函數內部它停止工作(也許exec功能並不像一個函數內使用!):

df = pd.DataFrame({"A" : [6, 2, 10, -5, 3], 
        "B" : [2, 5, 3, 2, 6], 
        "C" : [-5, 2, 1, 8, 2]}) 
limits_dic = {"A" : 0, "B" : 2, "C" : -1} 
def filtering(df, limits_dic): 
    cond = "df = df.loc[" 
    for key in limits_dic.keys(): 
     cond += "(df." + key + " > " + str(limits_dic[key])+ ") & " 
    cond = cond[:-2] + "].reset_index(drop = True)" 
    exec(cond) 
    return(df) 

df = filtering(df, limits_dic) 
df 
    A B C 
0 6 2 -5 
1 2 5 2 
2 10 3 1 
3 -5 2 8 
4 3 6 2 

我知道一個函數內部使用,但不知道如何解決這個問題時exec函數的作用是不同的。此外,我想知道必須有一個更優雅的方式來定義一個函數來做兩個輸入的過濾:1)df和2)limits_dic = {"A" : 0, "B" : 2, "C" : -1}。我將不勝感激任何想法。

回答

9

如果您嘗試構建動態查詢,則有更簡單的方法。下面是一個使用列表理解和str.join

query = ' & '.join(['{} > {}'.format(k, v) for k, v in limits_dic.items()]) 
print(query) 

'A > 0 & C > -1 & B > 2' 

傳遞查詢字符串df.query,它意味着這個目的:

out = df.query(query) 
print(out) 

    A B C 
1 2 5 2 
2 10 3 1 
4 3 6 2 

你也可以使用df.eval,如果你想獲得一個布爾掩碼爲您的查詢,然後索引變得簡單明瞭之後:

mask = df.eval(query) 
print(mask) 

0 False 
1  True 
2  True 
3 False 
4  True 
dtype: bool 

out = df[mask] 
print(out) 

    A B C 
1 2 5 2 
2 10 3 1 
4 3 6 2 
+2

^值得更多upvote! – piRSquared

+0

@cᴏʟᴅsᴘᴇᴇᴅ你的建議很完美。使用'exec'絕對不是實現這一目標的最佳方式。話雖如此,「exec」在函數內部行爲不同,這很奇怪。無論如何,我會堅持使用'pandas'的'query'和'eval'方法。再次感謝您的徹底解答。 – ahoosh