处理.csv中不需要的(独立)双引号

piztneat  于 2023-06-03  发布在  其他
关注(0)|答案(3)|浏览(217)

我试图使用Python的csv模块读取格式不正确的. csv文件。混乱的CSV看起来像这样:

"name","age","place","date"
"Jack","23","perth, australia","12aug
"Jackie","44","delhi, india","9dec
"Neel","12","austin, texas","1aug
"David","77","fresno, ca","21june

您会注意到每行末尾(日期列)缺少第二个双引号。
当我尝试使用下面的代码读取这个文件时,我得到:

import csv
import os
temp = csv.reader(open('/Desktop/test csv/quote_test.csv', "r"), delimiter=',')
for row in temp:
    print(row)
['name', 'age', 'place', 'date']
['Jack', '23', 'perth, australia', '12aug\nJackie"', '44', 'delhi, india', '9dec\nNeel"', '12', 'austin, texas', '1aug\nDavid"', '77', 'fresno, ca', '21june']

这是意料之中的,因为它将当前行的最后一个元素和下一行的第一个元素作为一个条目读取(直到它找到一个“,匹配最后一个,”)-跳过所有换行符。
我的问题是:-在Python中有没有更好的方法来处理这样混乱的csv,在那里我们可以为每一行至少获得正确数量的预期列(也就是说,在这种情况下,有没有一种方法可以让Python仍然考虑换行符),然后处理像<"12aug>,<" 9dec>等条目。分开吗如果没有,还有什么其他方法可以更好地使用python来理解这些数据?

zvms9eto

zvms9eto1#

在将数据传递给csv读取器之前,可以先检查行是否以"结尾,如果不存在,则追加"

import csv
import os

with open('/Desktop/test csv/quote_test.csv', "r") as f:
    data = f.read().splitlines()
for i, line in enumerate(data):
    if not line.endswith('"'):
        data[i] = line + '"'      
data = "\n".join(data)
       
temp = csv.reader(data, delimiter=',')
for row in temp:
    print(row)
czfnxgou

czfnxgou2#

由于数据的格式很差,csv模块很难按照您想要的方式解析它。
最好的方法是对文件进行预处理以清理数据。在这种情况下,您需要做的就是添加缺少的尾随双引号。

import csv
import os

with open('/Desktop/test csv/quote_test.csv', 'r') as f:
    data = [f'{line.strip()}"' if not line.strip().endswith('"') else line.strip() for line in f.readlines()]
    temp = csv.reader(data, delimiter=',')
    for row in temp:
        print(row)

请注意,这段代码去掉了换行符,以便将双引号附加到行的末尾。换行符 * 不会 * 添加回来(因为它们不是必需的)--但是如果需要,您可以轻松地添加回来。

ruyhziif

ruyhziif3#

问题是csv规范明确允许带引号的字段包含新行。换句话说,你的文件不是CSV文件,Python CSV模块无法处理它,无论配置如何。
这意味着需要预处理。如果你确定除了第一行以外的所有行的末尾都没有双引号,你可以在阅读标题后一致地添加双引号。如果你想更宽容(也许以后的文件会有那个该死的引号),你可以只在一行有偶数个引号的时候添加它(如果一个字段包含一个引号,它应该被加倍)。我将使用一个简单的生成器来修复文件:

def quote_adder(t):
    for line in t:
        line = line.strip()
        if (len([c for c in line if c == '"']) % 2) != 0:
            line += '"'
        yield line

with open('/Desktop/test csv/quote_test.csv', "r") as fd:
    for row in csv.reader(quote_adder(fd)):
        //process row

如果进程行是print(row),则按预期给出:

['name', 'age', 'place', 'date']
['Jack', '23', 'perth, australia', '12aug']
['Jackie', '44', 'delhi, india', '9dec']
['Neel', '12', 'austin, texas', '1aug']
['David', '77', 'fresno, ca', '21june']

相关问题