2017-02-27 47 views
0

我有幾個csv文件,其中每個文件都有不同的格式。這裏是兩個不同的csv文件的示例。請查看格式不是值。在python中解析兩種不同類型的csv格式

csv_2 "xxxx-0147-xxxx-194443,""Jan 1, 2017"",7:43:43 AM PST,,Google fee,,Smart Plan (Calling & Texting),com.yuilop,1,unlimited_usca_tariff_and,mimir,US,TX,76501,USD,-3.00,0.950210,EUR,-2.85" 
csv_2 "1305-xxxx-0118-54476..1,""Jan 1, 2017"",7:17:31 AM PST,,Google fee,,Smart Plan (Calling & Texting),com.yuilop,1,unlimited_usca_tariff_and,htc_a13wlpp,US,TX,79079,USD,-3.00,0.950210,EUR,-2.85" 
csv_1 GPA.xxxx-2612-xxxx-44448..0,2017-02-01,1485950845,Charged,m1,Freedom Plan (alling & Texting),com.yuilop,subscription,basic_usca_tariff_and,USD,2.99,0.00,2.99,,,07605,US 
csv:1 GPA.xxxx-6099-9725-56125,2017-02-01,1485952917,Charged,athene_f,Buy 100 credits (Calling & Texting),com.yuilop,inapp,100_credits,INR,138.41,0.00,138.41,Kolkata,West Bengal,700007,IN 

正如你看到csv_2包含「,有時‘’,然而csv_1是一個簡單的格式。我得到的需求所有的CSV和他們有很多和巨大的。我試圖以識別使用嗅探器方言自動但這是不夠的,我不明白的是有一個合理的迴應「」有沒有人誰可以的GUID我如何解決這個問題呢?

Python代碼2.7

With open(file, 'rU') as csvfile: 
    dialect = csv.Sniffer().sniff(csvfile.read(2024)) 
    csvfile.seek(0) 
    reader = csv.reader(csvfile, dialect) 
    for line in reader: 
     print line 

參數值:

dialect.escapechar  None 
dialect.quotechar  " 
dialect.quoting  0 
dialect.escapechar  None 
dialect.delimiter  , 
dialect.doublequote False 

結果

csv_1 ['GPA.13xx-xxxx-9725-5xxx', '2017-02-01', '1485952917', 'Charged', 'athene_f', 'Buy 100 credits (Calling & Texting)', 'com.yuilop', 'inapp', '100_credits', 'INR', '138.41', '0.00', '138.41', 'Kolkata', 'West Bengal', '700007', 'IN'] 
csv_2 ['1330-xxxx-5560-xxxx,"Jan 1', ' 2017""', '12:35:13 AM PST', '', 'Google fee', '', 'Smart Plan (Calling & Texting)', 'com.yuilop', '1', 'unlimited_usca_tariff_and', 'astar-y3', 'US', 'NC', '27288', 'USD', '-3.00', '0.950210', 'EUR', '-2.85"'] 

在csv_2,你看到一個爛攤子。日期由逗號分隔,特別是日期字段和所有被視爲字符串的行。如何更改我的代碼以獲得與csv_1相同的結果?

回答

0

爲什麼不預先處理CSV清理「和規範它,然後加載數據,如其他CSV?

+1

有一個問題,我不知道他們每個人的csv格式是什麼。有大約1000個csv文件,因此打開它們中的每一個都是一件耗時的工作,你有什麼建議嗎? –

+0

你需要知道有多少格式有1000個csv文件,畢竟你需要在解析所有csv文件後處理這些信息,不是嗎? –

+0

好的,你知道我不會立即收到所有文件,所以我不知道接下來會發生什麼!所以我認爲你的意思是像有異常,並找出不同的CSV格式,並分別與他們的行爲..我雖然嗅探器可以自動完成這項工作,我們不需要關心這部分。@安東尼奧Beamud –

0

你從工作中的一個步驟。所有你所要做的就是第一replace" s在csvfile,那麼你目前的做法將工作得很好

編輯:但是,如果你有興趣合併CSV文件中閱讀後分開的日期字符串,你最好的選擇是一個正則表達式我已經在我的原始答案中包含了一些代碼我已經從this older answer中複製了大部分Regex代碼

import re 
import csv 

with open(file, 'rU') as csvfile: 
    data = csvfile.read(2024) 
    # Remove the pesky double-quotes 
    no_quotes_data = data.replace('"', '') 

    dialect = csv.Sniffer().sniff(no_quotes_data); 

    csv_data = csv.reader(no_quotes_data.splitlines(), dialect) 

    pattern = r'(?i)(%s) +(%s)' 

    thirties = pattern % (
     "Sep|Apr|Jun|Nov", 
     r'[1-9]|[12]\d|30') 

    thirtyones = pattern % (
     "Jan|Mar|May|Jul|Aug|Oct|Dec", 
     r'[1-9]|[12]\d|3[01]') 

    feb = r'(Feb) +(?:%s)' % (
     r'(?:([1-9]|1\d|2[0-9]))') # 1-29 any year (including potential leap years) 

    result = '|'.join('(?:%s)' % x for x in (thirties, thirtyones, feb)) 
    r = re.compile(result) 

    for ind, phrase in enumerate(csv_data): 
     if r.match(phrase): 
      # If you've found a date string, a year string will follow 
      new_data[ind] = ", ".join(csv_data[ind:ind+2]) 
      del csv_data[ind+1] 

    for line in csv_data: print line 
+1

爲什麼你沒有使用嗅探器?那會自動找到所有的,對嗎? –

+1

你是對的,會的。這是一個非常好的方法。我只是假設明確地指定分隔符會使我的答案對你更明顯。你可以定義'dialect = csv.Sniffer()。sniff(new_data)'並將其作爲'csv.reader()'行的輸入:'csv.reader(new_data.splitlines(),dialect)'。注意:在刪除雙引號後,我會避免引用'csvfile',因爲原始的'csvfile'仍然有雙引號,'Sniffer'不會自動檢測CSV的正確分隔符/格式。 –

+0

我試過你的方法,日期不正確,結果是'Jan 1','2017'=>分開作爲單獨的字段,但是這應該是'2017年1月1日'。實際上,這是我在識別逗號作爲分隔符時遇到的問題,那麼日期字段也會分開,這不是我合理的結果。 –