簡體   English   中英

Python 3.5 csv 解析特殊字符

[英]Python 3.5 csv parsing with special characters

我有一個要解析為 csv 的文件。 該文件是一個導出文件,並以以下格式發送給我(逐行,每個文件包含數千行):

03:30:30  08:30:30 [15 August 2015] productid:123456789 manuf:987654321 case:12 pallet:1234 id:12 code:1234  12345  123  12

我想將數據放入一個 csv 文件中,如下所示:

local time, GMT time, date, product id, manuf id, case, pallet, id, code, company id, location, secondary code
03:30:30, 08:30:30, 15 August 2015, 123456789, 987654321, 12, 1234, 12, 1234, 12345, 123, 12

我已經成功地做到了這一點,但我相信使用了錯誤的工具。 我一直在使用如下所示的行:

import fileinput
for line in fileinput.FileInput("file",inplace=1):
    line = line.replace(":",",")

import fileinput
for line in fileinput.FileInput("file",inplace=1):
    line = line.replace("case"," ")

這給了我類似的東西..

l h, l min, ls, gmt h, gmt m, gmt s, date, product id, manuf id, case, pallet, id, code, company id, location, secondary code
03,30,30,08,30,30,15 August 2015, 123456789, 987654321, 12, 1234, 12, 1234, 12345, 123, 12

問題是:我必須使用連續的行將每個字符和單詞解析為 csv(描述符、冒號、括號等),並且在大型數據集上需要很長時間。 此外,我將其全部保存到輔助文件中,而不是原地寫入。 通過用逗號替換冒號,我的時間被分解為單獨的列。 我花了幾天的時間嘗試不同的選項並到達了正則表達式,但作為一個完整的 python 新手還沒有想出一個解決方案。 將時間從逗號分隔的塊重建為正確的格式可能更簡單,但我不知所措。 請協助。 提前致謝。

編輯:

我嘗試實施 Sparkeandshine 以及 Julian 版本的可行解決方案。 我最接近讓 Sparkeandshie 的版本工作,但我只能迭代一行; 解決方案中實際存在的那個,而不是整個文件。 我花了最后 24 次嘗試兩種解決方案的不同迭代,但無濟於事。 這是我所在的地方:

#!/usr/bin/env python

import csv
import os

inputFileName = 'test.txt'
outputFileName = 'finished.csv'

with open(inputFileName, newline='') as inFile, open(outputFileName,    'w', newline='') as outfile:
    r = csv.reader(inFile)
    w = csv.writer(outfile)

    line = '03:30:30 08:30:30 [15 August 2015] productid:123456789 manuf:987654321 case:12 pallet:1234 id:12 code:1234 12345 123 12'
str_list = line.split()

new_list = [str_list[0],
        str_list[1],
        ' '.join([item.strip('[]') for item in str_list[2:5]]), # '[15', 'August', '2015]'
        str_list[6].split(':')[1],
        str_list[7].split(':')[1],
        str_list[8].split(':')[1],
        str_list[9].split(':')[1],
        str_list[10].split(':')[1],
        str_list[12],
        str_list[13]
        ]

with open(inputFileName, newline='') as inFile, open(outputFileName, 'w', newline='') as outfile:
    r = csv.reader(inFile)
    w = csv.writer(outfile)

    for row in r:
        w.writerow(new_list)

編輯:下面的 Sparkandshines 解決方案非常適合設置線,但我發現我的一些數據具有不同長度的線。 例如,有時幾行會縮短幾“列”數據,或者最后三列可能重復兩次。 為了解決這個問題,我一直在使用“嘗試”和“除了錯誤,繼續”作為可能的長度。 使用這種方法,我會在最終文件中得到重復的行; 有沒有更好的方法來使用不同長度的線的 Sparkandshine 的解決方案? ...或者更容易找到重復的行(通過檢查/比較兩/三列)並刪除它們?

使用處理每一行,

line = '03:30:30 08:30:30 [15 August 2015] productid:123456789 manuf:987654321 case:12 pallet:1234 id:12 code:1234 12345 123 12'
str_list = line.split()

new_list = [str_list[0],
            str_list[1],
            ' '.join([item.strip('[]') for item in str_list[2:5]]), # '[15', 'August', '2015]'
            str_list[6].split(':')[1],
            str_list[7].split(':')[1],
            str_list[8].split(':')[1],
            str_list[9].split(':')[1],
            str_list[10].split(':')[1],
            str_list[12],
            str_list[13]
            ]

print(new_list)
# Output
['03:30:30', '08:30:30', '15 August 2015', '987654321', '12', '1234', '12', '1234', '123', '12']

寫入一個 csv 文件,

with open(filename, 'w') as f:
    writer = csv.writer(f)

    # write the file header
    fieldnames = ['local time', 'GMT time', 'date', 'product id', 'manuf id', 
            'case', 'pallet', 'id', 'code', 'company id', 'location', 'secondary code']
    writer.writerow(fieldnames)

    # process each line
    for line in lines:
        new_list = do_something()

        writer.writerow(new_list) # write to the file

或過程的所有行,並將結果保存到一個列表的列表,然后WIRTE與csv文件writerows

writer.writerows(lists)

完整的源代碼,

#!/usr/bin/env python
import csv

inputFileName = 'test.txt'
outputFileName = 'finished.csv'

with open(outputFileName, 'w') as outfile:
    w = csv.writer(outfile)

    # write the file header
    fieldnames = ['local time', 'GMT time', 'date', 'product id', 'manuf id', 
            'case', 'pallet', 'id', 'code', 'company id', 'location', 'secondary code']
    writer.writerow(fieldnames)


    # process each line
    with open(inputFileName, 'r') as inFile:
        for line in inFile:
            str_list = line.rstrip().split()
            new_list = [str_list[0],
                        str_list[1],
                        ' '.join([item.strip('[]') for item in str_list[2:5]]), # '[15', 'August', '2015]'
                        str_list[6].split(':')[1],
                        str_list[7].split(':')[1],
                        str_list[8].split(':')[1],
                        str_list[9].split(':')[1],
                        str_list[10].split(':')[1],
                        str_list[12],
                        str_list[13]]

            w.writerow(new_list) # write to the file

如果您的輸入文件結構已知,則不需要使用正則表達式,因為它們速度較慢。 對於您的情況,請嘗試使用類似於以下代碼的內容:

import csv
with open('destination.csv', 'w', newline='') as csvfile:
    csv_writer = csv.writer(csvfile, delimiter=',')
    ...  # get your data here, the next code is for one line of data
    values = line.split()
    values[2] = '{} {} {}'.format(values[2][1:], values[3], values[4][:-1])  # Get rid of square brackets
    for idx in range(5, 11):
        values[idx] = values[idx].split(':')[1]  # get the number values
    values.pop(3);  # remove separated month name
    values.pop(3);  # remove separated year

    csv_writer.writerow(values)

您只編輯需要它的數據,然后將整行寫入 csv。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM