2012-07-10 24 views
47

की पंक्तियों पर जटिल फ़िल्टर मैं पंक्तियों को प्रत्येक पंक्ति के फ़ंक्शन द्वारा फ़िल्टर करना चाहता हूं, उदा।पांडा: डेटाफ्रेम

def f(row): 
    return sin(row['velocity'])/np.prod(['masses']) > 5 

df = pandas.DataFrame(...) 
filtered = df[apply_to_all_rows(df, f)] 

या किसी अन्य अधिक जटिल, काल्पनिक उदाहरण के लिए,

def g(row): 
    if row['col1'].method1() == 1: 
    val = row['col1'].method2()/row['col1'].method3(row['col3'], row['col4']) 
    else: 
    val = row['col2'].method5(row['col6']) 
    return np.sin(val) 

df = pandas.DataFrame(...) 
filtered = df[apply_to_all_rows(df, g)] 

कैसे मैं ऐसा कर सकते हैं?

उत्तर

70

आप इस DataFrame.apply उपयोग कर सकते हैं, जो ज

In [3]: df = pandas.DataFrame(np.random.randn(5, 3), columns=['a', 'b', 'c']) 

In [4]: df 
Out[4]: 
      a   b   c 
0 -0.001968 -1.877945 -1.515674 
1 -0.540628 0.793913 -0.983315 
2 -1.313574 1.946410 0.826350 
3 0.015763 -0.267860 -2.228350 
4 0.563111 1.195459 0.343168 

In [6]: df[df.apply(lambda x: x['b'] > x['c'], axis=1)] 
Out[6]: 
      a   b   c 
1 -0.540628 0.793913 -0.983315 
2 -1.313574 1.946410 0.826350 
3 0.015763 -0.267860 -2.228350 
4 0.563111 1.195459 0.343168 
+1

इस स्थिति में 'आवेदन' करने की कोई आवश्यकता नहीं है। एक नियमित बुलियन सूचकांक ठीक काम करेगा। 'डीएफ [डीएफ ['बी]> डीएफ [' सी ']]'। ऐसी बहुत कम स्थितियां हैं जिन्हें वास्तव में 'लागू' की आवश्यकता होती है और यहां तक ​​कि कुछ जिन्हें इसे 'अक्ष = 1' के साथ चाहिए –

8

मान लीजिए मैं एक DataFrame था इस प्रकार है:

In [39]: df 
Out[39]: 
     mass1  mass2 velocity 
0 1.461711 -0.404452 0.722502 
1 -2.169377 1.131037 0.232047 
2 0.009450 -0.868753 0.598470 
3 0.602463 0.299249 0.474564 
4 -0.675339 -0.816702 0.799289 

मैं एक बूलियन मुखौटा बनाने के लिए पाप और DataFrame.prod उपयोग कर सकते हैं:

In [40]: mask = (np.sin(df.velocity)/df.ix[:, 0:2].prod(axis=1)) > 0 

In [41]: mask 
Out[41]: 
0 False 
1 False 
2 False 
3  True 
4  True 

तो मुखौटा का उपयोग DataFrame से चयन करने के लिए :

In [42]: df[mask] 
Out[42]: 
     mass1  mass2 velocity 
3 0.602463 0.299249 0.474564 
4 -0.675339 -0.816702 0.799289 
+2

वास्तव में, यह शायद एक बुरा उदाहरण था: 'np.sin' स्वचालित रूप से सभी तत्वों को प्रसारित करता है। क्या होगा अगर मैंने इसे कम बुद्धिमान फ़ंक्शन के साथ बदल दिया जो केवल एक समय में एक इनपुट को संभाल सकता है? – duckworthd

1

मैं duckworthd's answer पर टिप्पणी canot एक दिया अक्ष के साथ एक समारोह लागू होता है, है, लेकिन यह पूरी तरह से काम नहीं कर रहा। यह दुर्घटनाओं जब dataframe खाली है:

df = pandas.DataFrame(columns=['a', 'b', 'c']) 
df[df.apply(lambda x: x['b'] > x['c'], axis=1)] 

आउटपुट:

ValueError: Must pass DataFrame with boolean values only 

मेरे लिए यह, पांडा में एक बग की तरह दिखता है के बाद से {} निश्चित बूलियन मूल्यों का कोई मान्य समूह है।

संबंधित मुद्दे