【问题标题】:How to Replace a column in a CSV file in Python?如何在 Python 中替换 CSV 文件中的列?
【发布时间】:2010-11-12 16:06:20
【问题描述】:

我有 2 个 csv 文件。我需要将一个文件中的一列替换为另一个文件中的一列,但它们必须根据 ID 列保持排序。

这是一个例子:

文件1:

ID, transect, 90mdist                                      
1, a, 10,                                                  
2, b, 20,                                                
3, c, 30,     

文件2:

ID, transect, 90mdist                                
1, a, 50                                                   
2, b, 70                                                     
3, c, 90          

基本上我用正确的 90mdist 创建了一个新文件,我需要将它插入到旧文件中,但它必须与相同的 ID # 对齐。

据我了解,Python 将 csv 文件视为字符串。所以我可以使用字典或将数据转换为列表然后更改它?哪种方式最好?

任何帮助将不胜感激!!

【问题讨论】:

  • 在你的例子中 file2 已经更正了文件,不是吗?所以你可以重命名文件。
  • 由于这两个文件具有相同的 ID 值和列集,您的意思是要完全用第二个文件覆盖第一个文件吗?我不确定你所说的“插入”是什么意思——也许示例数据选择不当,你可以编辑以澄清(所需的输出和输入)?

标签: python csv


【解决方案1】:

Python 库中的CSV Module 就是您需要的。

它允许您读取和写入 CSV 文件,将行视为元组或项目列表。

只需读取具有更正值的文件,将其存储在以行 ID 为键的字典中。

然后读入第二个文件,用字典中的数据替换相关列并写出第三个文件。

完成。

【讨论】:

  • +1:写入第三个文件。不要尝试就地更新文件。
【解决方案2】:

拥有 csv 列表后,将一个矩阵中的列替换为另一个矩阵的一种简单方法是转置矩阵,替换行,然后转回您编辑的矩阵。以下是您的数据示例:

csv1 = [['1', 'a', '10'], ['2', 'b', '20'], ['3', 'c', '30']]
csv2 = [['1', 'a', '50'], ['2', 'b', '70'], ['3', 'c', '90']]

# transpose in Python is zip(*myData)
transposedCSV1, transposedCSV2 = zip(*csv1), zip(*csv2)
print transposedCSV1
>>> [['1', '2', '3'], ['a', 'b', 'c'], ['10', '20', '30']]

csv1 = transposedCSV1[:2] + [transposedCSV2[2]]
print csv1
>>> [['1', '2', '3'], ['a', 'b', 'c'], ['50', '70', '90']]

csv1 = zip(*csv1)
print csv1
>>> [['1', 'a', '50'], ['2', 'b', '70'], ['3', 'c', '90']]

【讨论】:

    【解决方案3】:

    如果您只是一次性完成此操作,那么为什么还要为 Python 操心呢? Excel 或 OpenOffice Calc 将为您打开两个 CSV 文件,然后您可以将列从一个剪切并粘贴到另一个。

    如果这两个 ID 列表不完全相同,那么一个简单的 VB 宏会为您完成。

    【讨论】:

    • 我喜欢第一种方法(使用 excel/calc),但是写一个 VB 宏和写一个小 Python 脚本是一样的。
    【解决方案4】:

    试试这个:

    from __future__ import with_statement
    
    import csv
    
    def twiddle_csv(file1, file2):
        def mess_with_record(record):
            record['90mdist'] = 2 * int(record['90mdist']) + 30
        with open(file1, "r") as fin:
            with open(file2, "w") as fout:
                fields = ['ID', 'transect', '90mdist']
                reader = csv.DictReader(fin, fieldnames=fields)
                writer = csv.DictWriter(fout, fieldnames=fields)
                fout.write(",".join(fields) + '\n')
                reader.next()   # Skip the column header
                for record in reader:
                    mess_with_record(record)
                    writer.writerow(record)
    
    if __name__ == '__main__':
        twiddle_csv('file1', 'file2')
    

    几个注意事项:

    • DictReader 似乎使用了第一行 作为数据,即使它匹配 字段。调用 reader.next() 跳过。
    • 数据行不能有尾随逗号。它们将被解释为空列。
    • DictWriter 似乎没有写出列标题。自己动手做。

    【讨论】:

    • 感谢您提供样品。 (至少对于 csv.reader 和 csv.writer 而言)python csv 模块要求您以二进制模式打开文件,否则您会意外换行(请参阅bugs.python.org/issue7198)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-20
    • 1970-01-01
    • 2022-12-07
    • 2015-03-09
    • 1970-01-01
    • 1970-01-01
    • 2017-01-21
    相关资源
    最近更新 更多