【问题标题】:update existing csv file with updated info in another csv file用另一个 csv 文件中的更新信息更新现有 csv 文件
【发布时间】:2021-10-19 01:25:25
【问题描述】:

我有 2 个 csv 文件,

  • 文件zulu 包含基本信息,分列。
  • 文件bommel 仅更新了相同列中具有相同记录的信息。

我想在没有 Pandas 或其他外部资源的情况下在 Python 中解决这个问题(使用标准库中的 csv 模块)。

#!/usr/bin/env python3
import csv

# Define column names
fields = ['capcode', 'discipline', 'region', 'location', 'description', 'remark']

# Open the neccesary files
with open('bommel_db_capcodes.txt', 'r') as readFile_bommel:
    with open('results.csv', 'w') as results:
            with open('zulu_db_capcodes.txt', 'r') as readFile_zulu:
                master = csv.DictReader(readFile_zulu, fieldnames=fields)
                update = csv.DictReader(readFile_bommel, fieldnames=fields)
                writer = csv.DictWriter(results, fieldnames=fields)

                # Saves and skips header to output file
                writer.writerow(next(master))

                # Goes through whole zulu csv
                for row in master:
                    for row2 in update:
                        if row['capcode'] in update:
                            writer.writerow(row2)
                        else:
                            writer.writerow(row)

ReadFilezulu.close()
ReadFilebommel.close()
results.close()

zulucsv的内容:

capcode,discipline,region,location,description,remark
000400001,Brandweer,Groningen,Groningen,Regionaal,Pelotonscommandant Logistiek/Water (Noord)
000400002,Brandweer,Groningen,Groningen,,
000400003,Brandweer,Groningen,Groningen,Regionaal,Pelotonscommandant Logistiek/Water) (Oost)
000100000,Brandweer,Amsterdam-Amstelland,Amsterdam-Amstelland,Aalsmeer,Postalarm
000100001,Brandweer,Amsterdam-Amstelland,Amsterdam-Amstelland,,
000100002,Brandweer,Amsterdam-Amstelland,Amsterdam-Amstelland,,Banaanzulu
000100003,Brandweer,Amsterdam-Amstelland,Amsterdam-Amstelland,,

bommelcsv的内容:

capcode,discipline,region,location,description,remark
000100000,Brandweer,Amsterdam-Amstelland,,banaanProefalarm,
000100001,Brandweer,Amsterdam-Amstelland,Aalsmeer,Bevelvoerders,
000100004,Brandweer,Amsterdam-Amstelland,Aalsmeer,Korpsalarm,

当前结果

capcode,discipline,region,location,description,remark
000400001,Brandweer,Groningen,Groningen,Regionaal,Pelotonscommandant Logistiek/Water (Noord)
000400001,Brandweer,Groningen,Groningen,Regionaal,Pelotonscommandant Logistiek/Water (Noord)
000400001,Brandweer,Groningen,Groningen,Regionaal,Pelotonscommandant Logistiek/Water (Noord)

预期结果

capcode,discipline,region,location,description,remark                                            < from saving header
000400001,Brandweer,Groningen,Groningen,Regionaal,Pelotonscommandant Logistiek/Water (Noord)     < from zulu
000400002,Brandweer,Groningen,Groningen,,                                                        < from zulu
000400003,Brandweer,Groningen,Groningen,Regionaal,Pelotonscommandant Logistiek/Water) (Oost)     < from zulu
000100000,Brandweer,Amsterdam-Amstelland,,banaanProefalarm,                                      < from bommel
000100001,Brandweer,Amsterdam-Amstelland,Aalsmeer,Bevelvoerders,                                 < from bommel
000100002,Brandweer,Amsterdam-Amstelland,Amsterdam-Amstelland,,Banaanzulu                        < from zulu
000100003,Brandweer,Amsterdam-Amstelland,Amsterdam-Amstelland,,                                  < from zulu
000100004,Brandweer,Amsterdam-Amstelland,Aalsmeer,Korpsalarm,                                    < from bommel

关于如何完成这项工作的任何想法?

【问题讨论】:

  • 您需要以特定方式对行进行排序吗?如果有,怎么做?
  • 不,排序不是必需的,(可以很方便,在字段capcode上)

标签: python python-3.x csv export-to-csv


【解决方案1】:

当您第一次使用条件in update 时,您会消耗整个输入文件。因为update 基本上是一个生成器,所以当你循环遍历它时会耗尽它。

此外,您的条件检查更新文件中是否存在完全同一行,当然它不存在(如果数据完全相同,您将不希望或不需要更新任何内容)。

您想将更新行读入内存一次,然后当您看到具有相同键的行(不是整行!)时从主文件中跳过这些行(不是整行!)

我假设第一个字段 (capcode) 是这里的关键,但可能还有其他安排。

切线,您可以合并所有with 语句;而当你使用with open 时,就不需要.close() 任何东西了。

#!/usr/bin/env python3
import csv


fields = ['capcode', 'discipline', 'region', 'location', 'description', 'remark']

with open('bommel_db_capcodes.txt', 'r') as readFile_bommel, \
        open('results.csv', 'w') as results, \
        open('zulu_db_capcodes.txt', 'r') as readFile_zulu:

    master = csv.DictReader(readFile_zulu, fieldnames=fields)
    update = csv.DictReader(readFile_bommel, fieldnames=fields)
    writer = csv.DictWriter(results, fieldnames=fields)

    # Save header to output file and skip
    writer.writerow(next(master))

    # Skip header from updates
    next(update)

    # Read, remember, and write updated lines
    seen = set()
    for row in update:
        writer.writerow(row)
        seen.add(row['capcode'])

    for row in master:
        if row['capcode'] not in seen:
            writer.writerow(row)

演示:https://ideone.com/7Aj1PQ

【讨论】:

  • open 语句在 bommel 后的逗号上出现错误:-s ``` with open('bommel_db_capcodes.txt', 'r') as readFile_bommel, ^ ``` 当我使用您在途中打开文件后的解决方案,它就像一个魅力。我确实使用了错误的方法,认为它与in 声明有关。我以为它会检查 te 文件并停在具有匹配代码的行...
  • 就像演示中显示的那样,代码可以工作,尽管我在第一个版本中错过了该行的反斜杠;复制代码之前刷新页面了吗?
  • 不,我没有看到 \ 版本(还)。改变了它,就像一个魅力!很有帮助,谢谢!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-05
  • 2015-07-10
  • 2021-07-08
  • 1970-01-01
  • 1970-01-01
  • 2020-04-24
  • 1970-01-01
相关资源
最近更新 更多