2011-03-29 18 views
5

हमारे पास बहुत बड़ी फ़ाइलें हैं, कच्चे डेटा के साथ 1-1.5 जीबी संयुक्त (ज्यादातर लॉग फाइल) का क्रम जो आसानी से एक सीएसवी के लिए पारदर्शी है, जिसे बाद में उत्पन्न करने के लिए तैयार किया जाना चाहिए ग्राफ छवियों का एक सेट।बड़ी फ़ाइलों से पढ़ने वाले डेटा को पढ़ने और ग्राफिंग

वर्तमान में, हम कच्चे डेटा को एक सीएसवी फ़ाइल में बदलने के लिए बैश स्क्रिप्ट का उपयोग कर रहे हैं, केवल उन संख्याओं के साथ जिन्हें ग्रेन किया जाना चाहिए, और फिर इसे एक gnuplot स्क्रिप्ट में खिलााना। लेकिन यह प्रक्रिया बेहद धीमी है। मैंने कुछ पाइप cut एस, tr एस आदि को प्रतिस्थापित करके awk कमांड के साथ बैश स्क्रिप्ट को गति देने की कोशिश की, हालांकि यह गति में सुधार हुआ, पूरी बात अभी भी बहुत धीमी है।

तो, मुझे विश्वास है कि इस प्रक्रिया के लिए बेहतर उपकरण हैं। मैं वर्तमान में पाइथन + numpy या आर में इस प्रक्रिया को फिर से लिखना चाहता हूं। मेरा एक दोस्त JVM का उपयोग करने का सुझाव देता है, और यदि मैं ऐसा करना चाहता हूं, तो मैं क्लोजर का उपयोग करूंगा, लेकिन मुझे यकीन नहीं है कि JVM कैसे करेगा।

मुझे इस तरह की समस्याओं से निपटने में ज्यादा अनुभव नहीं है, इसलिए आगे बढ़ने के बारे में कोई सलाह बहुत अच्छी होगी। धन्यवाद।

संपादित करें: इसके अलावा, मैं जेनरेट किए गए इंटरमीडिएट डेटा, यानी, सीएसवी को (डिस्क पर) स्टोर करना चाहता हूं, इसलिए मुझे इसे फिर से उत्पन्न करने की ज़रूरत नहीं है, क्या मुझे चुनना चाहिए कि मैं एक अलग दिखने वाला ग्राफ चाहता हूं ।

संपादित करें 2: कच्चे डेटा फ़ाइलों में एक प्रति पंक्ति एक रिकॉर्ड होता है, जिनके फ़ील्ड एक डिलीमीटर (|) से अलग होते हैं। सभी फ़ील्ड संख्याएं नहीं हैं। इनपुट सीएसवी में मुझे आवश्यक प्रत्येक फ़ील्ड इनपुट रिकॉर्ड पर एक निश्चित सूत्र लागू करके प्राप्त किया जाता है, जो इनपुट डेटा से कई फ़ील्ड का उपयोग कर सकता है। आउटपुट सीएसवी में प्रति पंक्ति 3-4 फ़ील्ड होंगे, और मुझे उन ग्राफों की आवश्यकता है जो 1-2, 1-3, 1-4 फ़ील्ड को एक (हो सकता है) बार चार्ट में प्लॉट करें। मुझे उम्मीद है कि एक बेहतर तस्वीर देता है।

संपादित करें 3: मैंने @ एडीरौ की लिपि को थोड़ा सा संशोधित किया है और ऐसा लगता है कि यह बहुत अच्छी तरह से काम कर रहा है। मैं इतनी दूर आ गया हूं कि मैं डेटा पढ़ रहा हूं, प्रोसेसर थ्रेड्स (छद्म प्रसंस्करण, डेटा में थ्रेड नाम जोड़ना) के पूल में भेज रहा हूं, और इसे कलेक्टर थ्रेड के माध्यम से आउटपुट फ़ाइल में जोड़ रहा हूं।

पीएस: मुझे इस प्रश्न की टैगिंग के बारे में निश्चित नहीं है, इसे ठीक करने के लिए स्वतंत्र महसूस करें।

+0

उस आकार की फ़ाइलों के साथ आर मुश्किल हो सकती है, क्योंकि यह स्मृति-गहन है। आर की ग्राफिकल संभावनाएं पाइथन की तुलना में अधिक होती हैं (उदाहरण के लिए http://addictedtor.free.fr/graphiques/) देखें। सुनिश्चित करें कि आप आर (पैकेज बर्फबारी) में multithreading की जांच करें। लेकिन सबसे अधिक, कोड जिसमें आप परिचित हैं। यदि आप आर से बहुत परिचित नहीं हैं, तो इसे अनुकूलित करना मुश्किल होगा। –

+0

हां, यह भी एक और बिंदु है, मुझे आर में कोई अनुभव नहीं है, और numpy और matplotlib के साथ ही, लेकिन मैं अजगर के साथ बहुत सहज हूं। यह भी मेरी पसंद को प्रभावित करेगा। –

उत्तर

4

पायथन एक अच्छा विकल्प लगता है क्योंकि इसमें एक अच्छा थ्रेडिंग एपीआई है (कार्यान्वयन हालांकि संदिग्ध है), matplotlib और pylab। मुझे आपके अंत से कुछ और चश्मा याद आते हैं लेकिन शायद यह आपके लिए एक अच्छा प्रारंभिक बिंदु हो सकता है: matplotlib: async plotting with threads। मैं डेटा डिस्क प्रसंस्करण के लिए थ्रेड के पूल में क्यूइंग को कंक करने के लिए एक थ्रेड के लिए जाउंगा और डेटा प्रोसेसिंग के लिए धागे के पूल में क्यूइंग को सिंक कर रहा हूं (यदि आपने रिकॉर्ड की लंबाई निर्धारित की है तो चीजें प्रीकंप्यूटिंग रीड ऑफसेट्स द्वारा तेजी से हो सकती हैं और केवल थ्रेडपूल पर ऑफसेट को पास कर सकती हैं); डिस्कियो थ्रेड के साथ मैं डेटासॉर फाइलों को एमएमएपी करता हूं, एक पूर्वनिर्धारित num बाइट्स पढ़ता हूं + अंततः अंतिम डेटासेट्स लाइन इनपुट के अंत तक अंतिम बाइट्स को पकड़ने के लिए पढ़ता है; numbytes कहीं भी आपके औसत लाइनिनपुट लंबाई के पास चुना जाना चाहिए; अगला कतार के माध्यम से पूल खिला रहा है और डेटा प्रोसेसिंग/प्लॉटिंग जो थ्रेडपूल में होती है; मेरे पास यहां एक अच्छी तस्वीर नहीं है (आप वास्तव में क्या साजिश कर रहे हैं) लेकिन मुझे आशा है कि इससे मदद मिलती है।

संपादित करें: फ़ाइल है।रीडलाइन ([sizehint]) एक साथ कई लाइनों को पकड़ने के लिए; अच्छी तरह से यह बहुत तेजी से नहीं हो सकता है cuz डॉक्स कह रहे हैं इसके का उपयोग कर ReadLine() आंतरिक रूप से

संपादित करें: एक त्वरित कंकाल कोड

import threading 
from collections import deque 
import sys 
import mmap 


class processor(Thread): 
    """ 
     processor gets a batch of data at time from the diskio thread 
    """ 
    def __init__(self,q): 
     Thread.__init__(self,name="plotter") 
     self._queue = q 
    def run(self): 
     #get batched data 
     while True: 
      #we wait for a batch 
      dataloop = self.feed(self._queue.get()) 
      try: 
       while True: 
        self.plot(dataloop.next()) 
      except StopIteration: 
       pass 
      #sanitizer exceptions following, maybe 

    def parseline(self,line): 
     """ return a data struct ready for plotting """ 
     raise NotImplementedError 

    def feed(self,databuf): 
     #we yield one-at-time datastruct ready-to-go for plotting 
     for line in databuf: 
      yield self.parseline(line) 

    def plot(self,data): 
     """integrate 
     https://www.esclab.tw/wiki/index.php/Matplotlib#Asynchronous_plotting_with_threads 
     maybe 
     """ 
class sharedq(object): 
    """i dont recall where i got this implementation from 
    you may write a better one""" 
    def __init__(self,maxsize=8192): 
     self.queue = deque() 
     self.barrier = threading.RLock() 
     self.read_c = threading.Condition(self.barrier) 
     self.write_c = threading.Condition(self.barrier) 
     self.msz = maxsize 
    def put(self,item): 
     self.barrier.acquire() 
     while len(self.queue) >= self.msz: 
      self.write_c.wait() 
     self.queue.append(item) 
     self.read_c.notify() 
     self.barrier.release() 
    def get(self): 
     self.barrier.acquire() 
     while not self.queue: 
      self.read_c.wait() 
     item = self.queue.popleft() 
     self.write_c.notify() 
     self.barrier.release() 
     return item 



q = sharedq() 
#sizehint for readine lines 
numbytes=1024 
for i in xrange(8): 
    p = processor(q) 
    p.start() 
for fn in sys.argv[1:] 
    with open(fn, "r+b") as f: 
     #you may want a better sizehint here 
     map = mmap.mmap(f.fileno(), 0) 
     #insert a loop here, i forgot 
     q.put(map.readlines(numbytes)) 

#some cleanup code may be desirable 
+0

आपके विचारों के लिए धन्यवाद adirau, पायथन का उपयोग करने का मेरा इरादा इतना था कि मैं कतार से डेटा में पढ़ने वाले पूल वाले थ्रेड का उपयोग कर सकता था। एक बेहतर तस्वीर के लिए, मैंने अधिक जानकारी के साथ प्रश्न संपादित किया, उम्मीद है कि मैं जो भी कर रहा हूं उसका बेहतर विचार देता हूं। –

+0

कोड adirou के लिए आपका बहुत बहुत धन्यवाद, मेरे लिए कुछ समय लगेगा क्योंकि मैंने कभी 'डेक' और 'एमएमएपी' का उपयोग नहीं किया है। क्या आप उन पर अधिक जानकारी इंगित कर सकते हैं, 'queue.Queue' और 'deque' के बीच क्या अंतर है? और फाइल को बस क्यों नहीं खोलें और अनुक्रमिक रूप से इसकी रेखाएं पढ़ें? –

+0

collections.deque को तेजी से परिशिष्ट और पॉपलफ्ट परमाणु संचालन की पेशकश की जाती है जिसे लॉकिंग की आवश्यकता नहीं होती है (कतार दस्तावेज से स्निप करें); आप पाइथन दस्तावेज में डेक और एमएमएपी दस्तावेज़ ढूंढ सकते हैं; मैंने कुछ प्रकार के त्वरित अनुकूलन के रूप में थोक रेखा को पढ़ने का विकल्प चुना; एक-एक करके लाइनों को पढ़ना और कतारबद्ध करना एक बुरा विचार था (अधिक रीडलाइन कॉल, अधिक क्यूइंग ऑपरेशंस) इसलिए मैंने सोचा कि थोक पढ़ने और थोक प्रक्रिया के लिए यह बेहतर और तेज है; – user237419

1

मैं गति के बारे में, लगता है कि अजगर + Numpy लिए सबसे कारगर तरीका हो सकता है और कार्यान्वयन का आसानी। Numpy अत्यधिक अनुकूलित है इसलिए प्रदर्शन सभ्य है, और अजगर एल्गोरिदम कार्यान्वयन भाग को कम करेगा।

इस कॉम्बो को आपके मामले के लिए अच्छी तरह से काम करना चाहिए, जिससे आप स्मृति पर फ़ाइल की लोडिंग को अनुकूलित कर सकते हैं, डेटा ब्लॉक को प्रोसेस करने के बीच मध्य बिंदु खोजने का प्रयास करें जो बहुत बड़ा नहीं है लेकिन पढ़ने और लिखने के लिए काफी बड़ा है चक्र, क्योंकि यह प्रोग्राम को धीमा कर देगा

यदि आपको लगता है कि इसे और अधिक तेज़ करने की आवश्यकता है (जिसे मैं ईमानदारी से संदेह करता हूं), तो आप सुस्त भागों को तेज करने के लिए साइथन का उपयोग कर सकते हैं।

+0

मुझे आपका दूसरा पैराग्राफ नहीं मिला, क्या यह है कि अगर मैं '.read (2000) .splitlines()' करता हूं, तो यह प्रत्येक पंक्ति के लिए '.readline()' करने से बेहतर प्रदर्शन करेगा? –

+0

मैं सलाह दूंगा, क्योंकि यह पढ़ने और लिखने के चक्र को कम करेगा, फिर आपको कॉन्फ़िगरेशन के आधार पर इष्टतम आकार मिलना होगा ** readline() ** के बारे में एक और बात यह है कि यह आपको त्रुटियों का कारण बन सकता है क्योंकि यह कुछ बार पढ़ता है फाइल पढ़ने की तुलना में एक अलग क्रम में रेखाएं, विशेष रूप से जब फ़ाइल-पुनरावृत्ति को रीडलाइन के साथ मिलाते हैं – P2bM

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