基于ID号,根据另一个csv更新一个csv中的列

tyky79it  于 2023-09-28  发布在  其他
关注(0)|答案(2)|浏览(101)

我有两个包含如下数据的CSV(除了数百名学生):
Original.csv:
| ID|第一|最后|班主任|级|地址|电话|市|
| --|--|--|--|--|--|--|--|
| 11 |弗雷德|燧石族|贝蒂| 2 |1 Main Street| 555-1212|任何城镇|
| 22 |巴尼|瓦砾|威尔玛| 4 |石板街11号|555-1111|基岩|

Update.csv:
| ID|第一|最后|班主任|级|
| --|--|--|--|--|
| 11 |弗雷德|燧石族|史密斯| 2 |
| 22 |巴尼|瓦砾|琼斯| 4 |
我需要更新第一个CSV或创建一个新的CSV与Homeroom从Update.csv更新,使产生的文件包含所有的原始.csv列和数据,但更新Homeroom。
Result.csv:
| ID|第一|最后|班主任|级|地址|电话|市|
| --|--|--|--|--|--|--|--|
| 11 |弗雷德|燧石族|史密斯| 2 |1 Main Street| 555-1212|任何城镇|
| 22 |巴尼|瓦砾|琼斯| 4 |石板街11号|555-1111|基岩|
在搜索过程中,我发现并尝试了以下方法:

import csv #imports module csv

filea = "Original.csv"
fileb = "Updated.csv"
output = "Result.csv"

delim = "," #set your own delimiter

source1 = csv.reader(open(filea,"r"),delimiter=delim)
source2 = csv.reader(open(fileb,"r"),delimiter=delim)
#open csv readers

source2_dict = {}

# prepare changes from file B
for row in source2:
    source2_dict[row[0]] = row[1]

# write new changed rows
with open(output, "w") as fout:
    csvwriter = csv.writer(fout, delimiter=delim)
    for row in source1:
        # needs to check whether there are any changes prepared
        if row[1] in source2_dict:
            # change the item
            row[3] = source2_dict[row[1]]
        csvwriter.writerow(row)

它不像现在这样工作,我不确定改变“row[]”值是否会使它工作。无论我在不同的“row[]”区域中尝试了什么数字,我要么收到一个错误,要么结果文件不包含所需的更改。
我走的路对不对?我想根据ID列匹配学生。
谢谢你,谢谢!
我尝试在不更改输出文件的情况下,基于列索引更改行[]值
row[4] = source2_dict[row[1]]

n3schb8v

n3schb8v1#

您的解决方案有两个主要问题。第一个是你存储为source_dict2的中间字典,你把错误的值放进了它的键值中,你应该把homeroom放进row[3],而不是row[1]放进first name
第二个问题是你的查找和替换。因为你是通过使用row[0]ID作为键来给字典source_dict2赋值的,所以你需要查找这个值,而不是查找row[1]first name,因为它们都不是键。最后,在替换中,您再次需要使用row[0]作为source_dict2的键来获取替换值。

import csv #imports module csv

filea = "Original.csv"
fileb = "Updated.csv"
output = "Result.csv"

delim = "," #set your own delimiter

source1 = csv.reader(open(filea,"r"),delimiter=delim)
source2 = csv.reader(open(fileb,"r"),delimiter=delim)
#open csv readers

source2_dict = {}

# prepare changes from file B
# store the homeroom column
for row in source2:
    source2_dict[row[0]] = row[3]

# write new changed rows
with open(output, "w") as fout:
    csvwriter = csv.writer(fout, delimiter=delim)
    for row in source1:
        # needs to check whether there are any changes prepared
        # use the key column as the key to search for
        if row[0] in source2_dict:
            # change the item
            row[3] = source2_dict[row[0]] #again use the key column to get the value
        csvwriter.writerow(row)
yhived7q

yhived7q2#

我想建议你重新构造你的代码,尤其是过程。
我在阅读代码和跟踪source1source2时遇到了一些麻烦,我不知道现在应该发生什么,然后发生了什么?*.这个答案希望展示另一种思考代码和过程的方式。
也就是说,我建议将这个过程分成不同的阶段。程序最终在内存中保存了更多,但我认为它带来了一些清晰度,并允许调试任何特定阶段:
所有代码,从上到下:

updates: dict[str, str] = {}
with open("updates.csv", newline="", encoding="utf-8") as f:
    reader = csv.reader(f)
    for row in reader:
        updates[row[0]] = row[3]

new_rows: list[list[str]] = []
with open("original.csv", newline="", encoding="utf-8") as f:
    reader = csv.reader(f)
    for row in reader:
        row[3] = updates.get(row[0], row[3])
        new_rows.append(row)

with open("output.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.writer(f)
    writer.writerows(new_rows)

如果看起来有问题,在任意两个阶段之间添加print语句或断点,以查看出什么来和进什么来:

print(updates)

我们马上就可以看到,在收集更新时出现了问题:

{"ID": "First", "11": "Fred", "22": "Barney"}

也许你并不希望头文件成为更新的一部分,但它也有助于指出问题。

...
    for row in reader:
        updates[row[0]] = row[3]
{'ID': 'Homeroom', '11': 'Smith', '22': 'Jones'}

我通常不会完全使用“什么是 Pythonic”,但是使用get()和默认值来表达你想要保存更新或行的原始值似乎很清楚:

row[3] = updates.get(row[0], row[3])

相关问题