2011-06-15 14 views
6

डेटा मैं मिल गया है जो की तरह लग रहा विभाजित करने के लिए अजगर सीएसवी मॉड्यूल का उपयोग करने के लिए:कैसे डबल पाइप सीमांकित डेटा

"1234"||"abcd"||"a1s1" 

मैंने पढ़ा है और पायथन के सीएसवी पाठक और लेखक का उपयोग कर लिखने की कोशिश कर रहा हूँ। क्योंकि सीएसवी मॉड्यूल का डिलीमीटर एक सिंगल तक सीमित है, क्या डेटा को सुरक्षित रूप से पुनर्प्राप्त करने का कोई तरीका है? मैं खाली कॉलम को हटाने का जोखिम नहीं उठा सकता क्योंकि यह समय-समय पर संसाधित होने वाला एक विशाल विशाल डेटा सेट है। कोई विचार उपयोगी होगा।

+1

आपने कहा कि आप बस इसे जाना और फिर बाद में खाली कॉलम निकाल देने के लिए खर्च नहीं उठा सकते चारों ओर वैकल्पिक उद्धरण नष्ट करने के लिए। जब आपने कोशिश की तो यह किस कारक से धीमा था? –

+0

प्रश्नों को इंगित करना चाहिए कि क्या हम उदाहरण डेटा से सामान्यीकृत कर सकते हैं। मेरा जवाब नीचे 'हां' मानता है। –

उत्तर

12

The docs और प्रयोग साबित करते हैं कि केवल एकल-चरित्र डिलीमीटर की अनुमति है।

cvs.reader के बाद से स्वीकार करता है किसी भी वस्तु इटरेटर प्रोटोकॉल का समर्थन करता है कि, आप | -s साथ || -s को बदलने के लिए जनरेटर सिंटैक्स का उपयोग कर सकते हैं, और फिर पाठक को यह जनरेटर फ़ीड:

def read_this_funky_csv(source): 
    # be sure to pass a source object that supports 
    # iteration (e.g. a file object, or a list of csv text lines) 
    return csv.reader((line.replace('||', '|') for line in source), delimiter='|') 

इस कोड को बहुत प्रभावी है के बाद से यह एक समय में एक CSV लाइन पर चल रही है, अपनी CSV स्रोत पैदावार लाइनों है कि आपके उपलब्ध रैम :) से अधिक नहीं है प्रदान की

+7

संभावित रूप से डबल-पाइप डिलीमीटर का उपयोग क्यों किया जाता है क्योंकि किसी दिए गए मान में एक पाइप हो सकती है। – Arafangion

+0

@Arafangion: सच। शायद इस दोष को कम करने के लिए एक और विस्तृत जनरेटर अभिव्यक्ति की आवश्यकता है। –

+0

@Arafangion बस डबल-पाइप डिलीमीटरों को एक और डिलीमीटर (,;%%}^ø या जो कुछ भी) के साथ प्रतिस्थापित करें जो तब मान में नहीं होता है। –

1

दुर्भाग्य से, सीमांकक सी में एक चरित्र का प्रतिनिधित्व करती है इसका मतलब यह है कि यह यह असंभव है पी में एक ही चरित्र के अलावा कुछ भी हो Thon। अच्छी खबर यह है कि यह मान जो शून्य हैं अनदेखी करने के लिए संभव है:

reader = csv.reader(['"1234"||"abcd"||"a1s1"'], delimiter='|') 
#iterate through the reader. 
for x in reader: 
    #you have to use a numeric range here to ensure that you eliminate the 
    #right things. 
    for i in range(len(x)): 
     #Odd indexes will be discarded. 
     if i%2 == 0: x[i] #x[i] where i%2 == 0 represents the values you want. 

अन्य तरीके इस (एक समारोह, लिखा जा सकता है एक के लिए) पूरा करने के लिए कर रहे हैं, लेकिन यह आप तर्क जो की जरूरत है देता है ।

+0

आप कैसे संभालेंगे: '1234 || ab | cd || a1s1'? – Arafangion

+0

@Arafangion मूल उदाहरण सिर्फ पाइप चित्रित नहीं है, यह पाइप और डबल कोट चित्रित है। इसका मतलब है कि csv.reader लाइन के केंद्र में पाइप को अनदेखा कर देगा। – cwallenpoole

2
>>> import csv 
>>> reader = csv.reader(['"1234"||"abcd"||"a1s1"'], delimiter='|') 
>>> for row in reader: 
...  assert not ''.join(row[1::2]) 
...  row = row[0::2] 
...  print row 
... 
['1234', 'abcd', 'a1s1'] 
>>> 
1

अपने डेटा सचमुच (खेतों कभी नहीं होते हैं '||' और हमेशा उद्धृत कर रहे हैं), और आप उद्धरण चिह्न बर्दाश्त कर सकते हैं, या उन्हें बाद बंद काट करने को तैयार हैं उदाहरण की तरह लग रहा है, तो बस .split का उपयोग यदि सीमांकक के क्षेत्र में पाया जाता है

>>> '"1234"||"abcd"||"a1s1"'.split('||') 
['"1234"', '"abcd"', '"a1s1"'] 
>>> list(s[1:-1] for s in '"1234"||"abcd"||"a1s1"'.split('||')) 
['1234', 'abcd', 'a1s1'] 

सीएसवी केवल जरूरत है, या क्षेत्रों

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