首页 > 解决方案 > 在 Excel、R 和 Python 之间读取 CSV 文件时的互操作性问题

问题描述

我正在开展一个项目,该项目要求我使用他人的 R 代码和第三方的 Excel 电子表格独立验证我的 Python 代码的结果。(是的。)Python 能够读取包含源数据的 Excel 文件,但 R 脚本需要 CSV,并且对于解析由 Excel 或 pandas 生成的 CSV 不可靠,两次都静默失败。

我使用另存为...函数在 Excel 中生成了 CSV。在 pandas 中,我使用了以下命令:

inFile = 'data-parsed-for-R.xlsx'
Data = pd.read_excel(inFile)

for site, subframe in Data.groupby('Site'):
    outFile = site+'.csv'
    outPath = os.path.join(workingDirectory, site, 'Data')
    if not os.path.exists(outPath):
        os.makedirs(outPath)
    subframe.to_csv(path_or_buf=outPath+'\\'+outFile, na_rep='NA', header=['Foo', 'Bar', 'Baz', 'Qux', 'Quux', \
                                                                           'Quuux','Quuuux'], index=False)

我已经解决了这个问题 - 请参阅下面的解决方案;我提交了这个问题,希望其他人能够找到它,并可能对他们发现的其他互操作性问题发表评论。

标签: pythonrexcelcsvlanguage-interoperability

解决方案


在 R 中读取 Excel 生成的 CSV 文件

使用 Python 的open函数,我发现在 Excel 创建的 CSV 的开头有一组空白字符,当在 Excel 或任何记事本类型的应用程序中打开文件时,这些字符不会显示。是对应于 Windows 的 utf-8 代码的字节顺序标记 (BOM) EF BB BF,. (此问题在此处更详细地记录:Weirrd characters added to first column name after reading a toad-exported csv file。)我的解决方案:不要使用 Excel 为 R 生成 CSV 输入文件。我的另一个不太优选的解决方案:

import csv

with open('ExcelMade.csv') as fo:
    debug = fo.readlines()

debug[0] = debug[0][3:]

with open('ExcelMadeFixed.csv', 'w') as fo:
    write = csv.writer(fo)
    write.writerows(debug)

在 R 中读取 Pandas 生成的 CSV 文件

我在这里发现并解决了三个问题。两个与默认添加的索引有关,第三个与日期时间格式有关。

索引 = 假DataFrame.to_csv()写出 CSV 文件时应指定此选项。我在原始代码中发现了这一点,但我想记录它以防其他人第一次错过它。

index_col=(0)。事实证明,我之前用于清理和规范化数据的 Python 脚本已自动将索引列添加到 Excel 输出中。这对 pandas 无关紧要,但对 R 很重要。检查您的输入文件并将此选项添加到pd.read_excel()A 列中是否存在索引。

日期时间格式。默认情况下,Python 将日期时间类型的数据表示为YYYY-MM-DD HH:MM:SS. 我提供的 R 脚本需要日期时间为MM/DD/YY. 这也是一个简单的修复;您可以使用一个date_format选项。to_csv()

我的最终代码最终看起来像这样:

inFile = 'data-parsed-for-R.xlsx'
Data = pd.read_excel(inFile, index_col=(0))

for site, subframe in Data.groupby('Site'):
    outFile = site+'.csv'
    outPath = os.path.join(workingDirectory, site, 'Data')
    if not os.path.exists(outPath):
        os.makedirs(outPath)
    subframe.to_csv(path_or_buf=outPath+'\\'+outFile, na_rep='NA', header=['Foo', 'Bar', 'Baz', \
                                                                           'Qux', 'Quux', 'Quuux', \
                                                                           'Quuuux'], index=False, \
                                                                           date_format='%m/%d/%Y')

推荐阅读