【问题标题】:Make CSV escape Double Quotation Marks使 CSV 转义双引号
【发布时间】:2018-09-20 22:03:47
【问题描述】:

我需要准备一个 .csv 文件,以便处理它的程序(ArcMap)忽略双引号。 Arc 将该行上所有后续单元格的内容混合到任何包含双引号的先前单元格中。例如:

...根本不会再处理任何行。

如何使 CSV 转义双引号以在 ArcMap (10.2) 中成功处理?

【问题讨论】:

  • 请显示 CSV 的样子。它有类似3,"158... 24"" metal",46.2378,... 的东西吗?
  • 我的屏幕抓取不清晰吗?谢谢。
  • 您的屏幕截图显示了您正在使用的程序的解释,不幸的是,它并没有说明其中的实际内容。
  • 实际上,第一个屏幕截图是在处理之前。我只是显示相关的列和之后的列,因为那是受影响的。
  • 问题是 ArcMap。你无法控制它如何解释事物。您只需要了解它需要数据的方式即可。我个人不使用ArcMap,也不知道它在做什么。如果 ArcMap 接受其他格式,最好的选择是使用 CSV 以外的格式。如果您想尝试字符替换策略,我会选择(右双引号;又名“智能引号”对中的右引号)。如果 (a) 您出于某种原因确实需要直引号,或者 (b) ArcMap 存在“安全”ASCII 以外的字符问题,这可能不起作用。

标签: python python-2.7 csv arcmap


【解决方案1】:

假设df 是为 csv 文件创建的 DataFrame,如下所示

df = pd.read_csv('filename.csv')

让我们假设comments 是出现问题的列的名称,即您想用空字符串 () 替换每个双引号 (")。

以下单行代码会为您做到这一点。它将用空字符串替换df['comments'] 中每一行的每个双引号。

df['comments'] = df['comments'].apply(lambda x: x.replace('"', ''))

lambda 在变量x 中捕获df['comments'] 中的每一行。

编辑:要转义双引号,您需要将字符串转换为其原始格式。又是一个与上面非常相似的单行。

df['comments'] = df['comments'].apply(lambda x: r'{0}'.format(x))

字符串前的r是python中转义字符的转义。

【讨论】:

  • 感谢您的回答。除了我不想用空白替换双引号。这将有效地删除双引号,对吗?我只想转义双引号。
  • 谢谢。您的代码的哪一部分告诉 .csv 转义所有双引号?
  • 另外,你能确认一下“r'{0}'”中的零在做什么吗?
  • 字符串引号前的r 是对字符串的检查,例如,不要考虑转义字符。如果我想打印\n,我不能简单的print('\n'),因为它会打印一个换行符。在那种情况下,我会做print(r'\n')
  • 0 表示替换格式中的第 0 个索引元素,即x
【解决方案2】:

您可以尝试使用 csv 模块读取文件并将其写回,希望输出格式对您的其他工具更容易理解。请参阅formatting options 的文档。

import csv
with open('in.csv', 'r') as fin, open('out.csv', 'w') as fout:
    reader = csv.reader(fin, delimiter='\t')
    writer = csv.writer(fout, delimiter='\t')
    # alternative:
    # writer = csv.writer(fout, delimiter='\t', escapechar='\\', doublequote=False)
    for line in reader:
        writer.writerow(line)

【讨论】:

  • 谢谢。我执行了您的建议并得到了令人惊讶的结果。请查看我编辑的问题以了解具体输出。
  • @Waterman 这看起来很奇怪,但恐怕你必须自己调试,因为我不知道原始数据是什么。您可以尝试更改格式标志。
【解决方案3】:

对我有用的是编写一个模块来对 CSV 文件进行一些“预处理”,如下所示。关键行是“writer”具有参数“quoting=csv.QUOTE_ALL”的位置。希望这对其他人有用。

def work(Source_CSV):
    from __main__ import *
    import csv, arcpy, os

    # Derive name and location for newly-formatted .csv file
    Head = os.path.split(Source_CSV)[0]
    Tail = os.path.split(Source_CSV)[1]
    name = Tail[:-4]
    new_folder = "formatted"
    new_path = os.path.join(Head,new_folder)
    Formatted_CSV = os.path.join(new_path,name+"_formatted.csv")
    #arcpy.AddMessage("Formatted_CSV = "+Formatted_CSV)

    # Populate the new .csv file with quotation marks around all field contents ("quoting=csv.QUOTE_ALL")
    with open(Source_CSV, 'rb') as file1, open(Formatted_CSV,'wb') as file2:

        # Instantiate the .csv reader
        reader = csv.reader(file1, skipinitialspace=True)   

        # Write column headers without quotes
        headers = reader.next()  # 'next' function actually begins at the first row of the .csv.  
        str1 = ''.join(headers)
        writer = csv.writer(file2)
        writer.writerow(headers)

        # Write all other rows wrapped in double quotes
        writer = csv.writer(file2, delimiter=',', quoting=csv.QUOTE_ALL)

        # Write all other rows, at first quoting none...
        #writer = csv.writer(file2, quoting=csv.QUOTE_NONE,quotechar='\x01')

        for row in reader:
            # ...then manually doubling double quotes and wrapping 3rd column in double quotes.
            #row[2] = '"' + row[2].replace('"','""') + '"'
            writer.writerow(row) 

        return Formatted_CSV

【讨论】:

    猜你喜欢
    • 2020-02-21
    • 2013-07-22
    • 1970-01-01
    • 2020-11-26
    • 1970-01-01
    • 2013-06-17
    • 2013-08-09
    • 2015-09-06
    • 1970-01-01
    相关资源
    最近更新 更多