2016-01-13 37 views
1

的交集可以說我有以下數據框:功能相匹配的列和值列 - DataFrames

>>>df = pd.DataFrame([[5,2,3,11],[5,3,3,8],[9,4,11,12],[5,14,15,16]],columns=["a","b","c","d"]) 
>>>df 
    a b c d 
0 5 2 3 11 
1 5 3 3 8 
2 9 4 11 12 
3 5 14 15 16 

如果我想匹配這種種的列值的行:「A」等於5 ,「b」 < 10和「c」大於或等於3,我可以做到以下幾點:

df[(df['a'] == 5) & (df['b'] < 10) & (df['c'] >= 3)] 

而且會給我,結果我是後:

a b c d 
0 5 2 3 11 
1 5 3 3 8 

輸入該代碼以匹配行很費力,所以我決定創建一個名爲row_matcher的函數,該函數需要2個參數:一個Pandas DataFrame和一列長度爲3的列表 - 選擇列,運算符和值。

def get_operator_fn(op): 
    import operator 
    return { 
     '<' : operator.lt, 
     '<=' : operator.le, 
     '==' : operator.eq, 
     '!=' : operator.ne, 
     '>=' : operator.ge, 
     '>' : operator.gt, 
     '&' : operator.and_ 
     }[op] 

def row_matcher(df,parameters): 
    import pandas as pd 
    """Parameter should be [column,operation,value] 
    Example: ['trial',"==",1] 
    """ 
    operations = [df[get_operator_fn(operation)(df[column],value)] for column,operation,value in parameters] 
    return reduce(lambda left,right: pd.merge(left,right,how='inner'), operations) 

>>>row_matcher(df,[["a","==",5],["b","<",10],["c",">=",3]]) 

不幸的是,此代碼就拋出了一個錯誤的return reduce(...)行: TypeError: Could not compare <type 'str'> type with Series

我試着用替換return reduce(...)行: df[reduce(operator.and_,operations)]

這仍然導致錯誤:TypeError: unsupported operand type(s) for &: 'str' and 'str'

我希望有任何幫助。

回答

4

我認爲這會使用query()方法簡單得多。用這種方法,你最初的例子可以寫成:

df.query('a==5 & b<10 & c>=3') 

老實說,如果你使用query()方法,我不認爲你會從你的函數多少收穫,除非你是在地段正在閱讀來自外部文件的條件。如果還想編寫row_matcher函數,只需使用字符串連接將列表的列表組合爲單個字符串,即可使用query()語法。一旦你有一個字符串,將它傳遞給query()方法。

您可能需要安裝numexpr模塊才能使用query()方法。您可以通過將關鍵字參數engine='python'提供給query()方法來解決此問題。這可能比使用numexpr模塊效率低,所以如果性能成爲問題,安裝模塊可能是值得的。

+0

我不得不安裝並導入numexpr模塊才能使其正常工作。 – floydn

+0

@floydn:我也是。我不知道這是否只是我錯過了它,或者它是否可能經常缺失。我將編輯我的答案以解決可以提供的關鍵字參數以避免使用numexpr。 – root