2010-09-04 11 views
9

स्टैकओवरफ्लो ने वर्तमान प्रश्न का शीर्षक लेकर Google के अनुसार 10,000 सबसे आम अंग्रेजी शब्दों को हटाकर अपने "संबंधित प्रश्न" सुविधा को लागू किया। शेष प्रश्नों को संबंधित प्रश्नों को ढूंढने के लिए पूर्ण टेक्स्ट खोज के रूप में सबमिट किया जाता है।पायथन/Django में शब्दों की एक लंबी सूची के खिलाफ एक स्ट्रिंग को कुशलतापूर्वक फ़िल्टर कैसे करें?

मैं अपने Django साइट में कुछ ऐसा करना चाहता हूं। पायथन में शब्दों की एक लंबी सूची के खिलाफ एक स्ट्रिंग (इस मामले में प्रश्न शीर्षक) फ़िल्टर करने का सबसे अच्छा तरीका क्या है? कोई पुस्तकालय जो मुझे कुशलता से ऐसा करने में सक्षम बनाता है?

उत्तर

10

आप पाइथन में सेट और स्ट्रिंग कार्यक्षमता का उपयोग करके इसे बहुत आसानी से कर सकते हैं और देख सकते हैं कि यह कैसा प्रदर्शन करता है (समयपूर्व अनुकूलन सभी बुराइयों की जड़ है!):

common_words = frozenset(("if", "but", "and", "the", "when", "use", "to", "for")) 
title = "When to use Python for web applications" 
title_words = set(title.lower().split()) 
keywords = title_words.difference(common_words) 
print(keywords) 
2

मैं नहीं जानता कि कौन सी विधि एसओ द्वारा किया जाता है, लेकिन:

मुझे लगता है ऐसा करने का एक तेजी से (और बहुत साधारण) जिस तरह से वापस सी के लिए जा रहा है, और उन्हें एक के बाद एक जाँच, हो सकता है कर रहा है KMP एल्गोरिदम के साथ।

ऐसा करने का एक और (इतना आसान नहीं), उन 10.000 शब्दों के साथ trie रखकर और उस का उपयोग करके टेक्स्ट खोजना है। यह सुपर-फास्ट होगा, लेकिन लागू करने के लिए काफी मुश्किल है। यदि आप रुचि रखते हैं, तो मेरे पास सी ++ में डमी कार्यान्वयन है।

संपादित

इसे वापस करने के लिए देख रहे हैं, मैं तुम्हें be able to integrate with python easily हूँ तो देख मैं केवल fstream का उपयोग किया है, तो यह सी के लिए आसानी से संशोधित किया जा सकता है।

#include <fstream> 
using namespace std; 

ifstream in("trie.in"); 
ofstream out("trie.out"); 

struct Trie 
{ 
    short nr, pref; 
    Trie *children[26], *father; 
    Trie() 
    { 
     int i; 
     nr = pref = 0; 
     for(i=0; i<26; i++) 
      children[i] = NULL; 
     father = NULL; 
    } 
}; 

Trie t, *it, *it2; 
int n, op, val, i, l, len; 
char s[22],*p; 

int main() 
{ 
    while(in>>op>>s) 
    { 
     p = s; 
     it = &t; 
     l = 0;len=0; 
     while(p[0] != '\0') 
     { 
      if(it->children[p[0] - 'a'] == NULL && op == 2) 
       {op=9; out<<"0\n"; break;} 
      if(it->children[p[0] - 'a'] == NULL && op == 3) 
       break; 
      if(it->children[p[0] - 'a'] == NULL) 
       it->children[p[0] - 'a'] = new Trie(), it->children[p[0] - 'a']->father = it, 
         it = it->children[p[0] - 'a']; 
      else 
       it = it->children[p[0] - 'a']; 
      if(op == 0) 
       ++ it->pref; 
      else if(op == 1 && it->pref > 0) 
       -- it->pref; 
      else if(op == 3 && it->pref > 0) 
       l = p-s+1; 

      p++; 
     } 
     if(op == 0) 
      it->nr ++; 
     else if(op == 1 && it->nr > 0) 
     { 
      it->nr --; 
      l = strlen(s)-1; 
      while(it->pref == 0 && it != &t && l>=0) 
      { 
       it2 = it->father; 
       it2->children[s[l--] - 'a'] = NULL; 

       delete it; 
       it = it2; 
      } 

     } 
     else if(op == 2) 
      out<<it->nr<<'\n'; 
     else if(op == 3) 
      out<<l<<'\n'; 

    } 
    return 0; 
} 

यह लेता है trie.in पाठ में इस प्रकार फ़ॉर्मेट:: यह स्रोत है

0 lat 
0 mare 
0 lac 
2 la 
0 mare 
1 lat 
0 ma 
0 lung 
3 latitudine 
0 mari 
2 mare 
0 lat 
0 mic 
3 latime 
2 lac 
3 mire 

और यह

0 
2 
2 
3 
1 
2 

0 डब्ल्यू की तरह पाठ का उत्पादन - शब्द सूची में डब्ल्यू जोड़ने (कई बार हो सकता है)

1 डब्ल्यू - सूची से शब्द डब्ल्यू का एक रिकॉर्ड हटाएं (क्या कई बार हो सकता है)

2 डब्ल्यू - प्रिंट कितने शब्द डब्ल्यू सूची में

3 डब्ल्यू देखते हैं - सबसे लंबे समय तक सामान्य सूची

ओह में किसी भी अन्य शब्द के साथ w का उपसर्ग की लंबाई प्रिंट , और खराब स्वरूपण के लिए खेद है, यह प्रशिक्षण के लिए किया गया था।

+0

कृपया अपने trie कार्यान्वयन साझा करते हैं, मैं निश्चित रूप से दिलचस्पी रखता हूँ। मैं पाइथन प्रोग्राम से आपके सी ++ कार्यान्वयन का उपयोग कैसे करूं? – Continuation

2

मुझे लगता है कि एक बहुत ही सरल समाधान और अभी भी उचित रूप से तेज़ स्क्लाइट और नियमित अभिव्यक्तियों का उपयोग करना है।

एक एसक्लाइट तालिका में शब्दों की लंबी सूची रखें और बी-पेड़ इंडेक्स बनाएं। यह आपको लॉग (एन) समय मौजूद प्रश्न पूछता है। छोटी स्ट्रिंग को एक नियमित अभिव्यक्ति के साथ विभाजित करें और उनमें से प्रत्येक के लिए एक मौजूदा क्वेरी चलाने वाले शब्दों पर लूप करें।

आप पहले एनएलटीके से पोर्टर स्टेमर के साथ शब्दों को स्टेम कर सकते हैं।

+0

क्यों नहीं 'शब्द =' शब्द 1 'या शब्द =' word2 '...' और इसे एक प्रश्न में करते हैं? – aaronasterling

+0

एक विसंगतिपूर्ण क्वेरी आपको बताएगी कि क्या कोई भी शब्द तालिका में है, लेकिन कौन सा नहीं, जो मुझे लगता है कि सवाल क्या है। – Kevin

+0

ओह हाँ, अब स्पष्ट है। – aaronasterling

2

मैं एक Trie की तरह कुछ शांत के उपयोग को हतोत्साहित करने के लिए नफरत है, आप सीधे अजगर में यह करने के बारे में सोचा है? मैंने corncob worlist का उपयोग करके एक सरल बेंचमार्क लिखा और प्रदर्शन इतना बुरा नहीं था।

import time 

with open('corncob_lowercase.txt') as f: 
    filetime = 0 
    starttime = time.time() 
    words = f.read().split('\n') 
    endtime = time.time() 
    filetime = endtime - starttime 
    print "file opened in {0} seconds".format(filetime)  
    nonwords = ['234' + word for word in words] 
    totaltime = 0 
    for word in nonwords: 
     starttime = time.time() 
     word in words 
     endtime = time.time() 
     totaltime += endtime - starttime 
    wordcount = len(words) 
    avgtime = totaltime/wordcount 
    print "average time for word: {0}".format(avgtime) 
    print "with {0} words".format(wordcount) 
    runningtimes = (filetime + i * avgtime for i in xrange(10)) 
    print "running times: {0}".format(list(runningtimes)) 

ध्यान दें कि मैं सबसे बुरी स्थिति का परीक्षण कर रहा हूं जहां शब्द फ़ाइल में नहीं है। मैं फ़ाइल लोड करने और फ़ाइल को संसाधित करने का समय भी शामिल कर रहा हूं। यदि आप इसे याद करना चाहते थे, तो वह गायब हो जाएगा। ध्यान देने योग्य एक और बात यह है कि मेरी मशीन मूल रूप से बकवास है। सी तेज है लेकिन सूची खोजने में शामिल अधिकांश कोड सी में किसी भी तरह लिखा गया है। अंत में, यह परीक्षण अंग्रेजी भाषा में हर शब्द के लिए है। यदि आप सिर्फ 10,000 चाहते हैं, तो मुझे लगता है कि केक है।

file opened in 0.0135519504547 seconds 
average time for word: 0.00249605141253 
with 58113 words 
running times: [0.013551950454711914, 0.016048001867237236, 0.018544053279762558, 
0.021040104692287877, 0.023536156104813199, 0.026032207517338521, 0.028528258929863839, 
0.031024310342389162, 0.033520361754914484, 0.036016413167439809] 
1

यदि कुछ झूठी सकारात्मक/नकारात्मक हैं ठीक है, तो विकिपीडिया पर ब्लूम फ़िल्टर की खोज करें।

यदि सीडीबी नहीं देखते हैं, (yum tinycdb इंस्टॉल करें, फेडोरा में - कोई पायथन एपीआई एटीएम नहीं)।

0

कैसे अजगर के बहुत अच्छा filter विधि का उपयोग कर के बारे में:

common_words = set(("if", "but", "and", "the", "when", "use", "to", "for")) 
title = "When to use Python for web applications" 
print filter(lambda word: word not in common_words, title.lower().split()) 
संबंधित मुद्दे