我正在尝试合并两个csv文件并保留重复记录。每个文件可能具有匹配的记录,一个文件可能具有重复的记录(具有不同测试分数的相同学生ID),并且一个文件可能在另一个文件中没有匹配的学生记录。下面的代码按预期工作,但是如果存在重复记录,则只将第二条记录写入合并文件。我已查看了许多线程,并且所有地址都删除了重复项,但我需要保留重复的记录。
import csv
from collections import OrderedDict
import os
cd = os.path.dirname(os.path.abspath(__file__))
fafile = os.path.join(cd, 'MJB_FAScores.csv')
testscores = os.path.join(cd, 'MJB_TestScores.csv')
filenames = fafile, testscores
data = OrderedDict()
fieldnames = []
for filename in filenames:
with open(filename, 'r') as fp:
reader = csv.DictReader(fp)
fieldnames.extend(reader.fieldnames)
for row in reader:
data.setdefault(row['Student_Number'], {}).update(row)
fieldnames = list(OrderedDict.fromkeys(fieldnames))
with open('merged.csv', 'w', newline='') as fp:
writer = csv.writer(fp)
writer.writerow(fieldnames)
for row in data.values():
writer.writerow([row.get(fields, '') for fields in fieldnames])
fafile:
Student_Number Name Grade Teacher FA1 FA2 FA3
65731 Ball, Peggy 4 Bauman, Edyn 56 45 98
65731 Ball, Peggy 4 Bauman, Edyn 32 323 232
85250 Ball, Jonathan 3 Clarke, Mary 65 77 45
981235 Ball, David 5 Longo, Noel 56 89 23
91851 Ball, Jeff 0 Delaney, Mary 83 45 42
543 MAX 2 Phil 77 77 77
543 MAX 2 Annie 88 888 88
9844 Lisa 1 Smith, Jennifer 43 44 55
testscores:
Student_Number Name Grade Teacher MAP Reading MAP Math FP Level DSA LN DSA WW DSA SJ DSA DC
65731 Ball, Peggy 4 Bauman, Edyn 175 221 A 54 23 78 99
72941 Ball, Amanda 4 Bauman, Edyn 201 235 J 65 34 65
85250 Ball, Jonathan 3 Clarke, Mary 189 201 L 34 54
981235 Ball, David 5 Longo, Noel 225 231 D 23 55
91851 Ball, Jeff 0 Delaney, Mary 198 175 C
65731 Ball, Peggy 4 Bauman, Edyn 200 76 Y 54 23 78 99
543 MAX 2 Phil 111 111 Z 33 44 55 66
543 MAX 2 Annie 222 222 A 44 55 66 77
当前输出:
Student_Number Name Grade Teacher FA1 FA2 FA3 MAP Reading MAP Math FP Level DSA LN DSA WW DSA SJ DSA DC
65731 Ball, Peggy 4 Bauman, Edyn 32 323 232 200 76 Y 54 23 78 99
85250 Ball, Jonathan 3 Clarke, Mary 65 77 45 189 201 L 34 54
981235 Ball, David 5 Longo, Noel 56 89 23 225 231 D 23 55
91851 Ball, Jeff 0 Delaney, Mary 83 45 42 198 175 C
543 MAX 2 Annie 88 888 88 222 222 A 44 55 66 77
72941 Ball, Amanda 4 Bauman, Edyn 201 235 J 65 34 65
9844 Lisa 1 Smith, Jennifer 43 44 55
期望的输出:
Student_Number Name Grade Teacher FA1 FA2 FA3 MAP Reading MAP Math FP Level DSA LN DSA WW DSA SJ DSA DC
65731 Ball, Peggy 4 Bauman, Edyn 32 323 232 200 76 Y 54 23 78 99
65731 Ball, Peggy 4 Bauman, Edyn 56 45 98 175 221 A 54 23 78 99
85250 Ball, Jonathan 3 Clarke, Mary 65 77 45 189 201 L 34 54
981235 Ball, David 5 Longo, Noel 56 89 23 225 231 D 23 55
91851 Ball, Jeff 0 Delaney, Mary 83 45 42 198 175 C
543 MAX 2 Annie 88 888 88 222 222 A 44 55 66 77
543 MAX 2 Phil 77 77 77 111 111 Z 33 44 55 66
72941 Ball, Amanda 4 Bauman, Edyn 201 235 J 65 34 65
9844 Lisa 1 Smith, Jennifer 43 44 55
答案 0 :(得分:0)
您正在使用OrderedDict
来存储两个文件中的学生ID(密钥)及其记录(值)。
这有一个微妙的含义:新的学生ID 条目将替换上一个文件中旧的重复的学生ID dict条目,因为dict键是唯一的。
您可以考虑在从一个文件中读取条目后立即将条目写入 merge 文件。之后,dict
被清除,下一个文件用于重新填充 dict
。这有助于避免学生ID的碰撞和替换。
答案 1 :(得分:0)
对于内循环,您可以执行以下操作:
for row in reader:
new_record = dict(row)
records = data.setdefault(row['Student_Number'], [])
for record in records:
new_record.update(record) # preserve old values
record = copy.copy(new_record)
new_record.update(dict(row)) # to preserve original values
records.append(new_record)
写作时你必须更进一步:
for rows in data.values():
for row in rows:
writer.writerow(row)
开头添加"导入副本"。我是从头开始写的,可能需要一些调整。
基本上这样做会以列表的形式添加另一个图层,您可以使用新图层更新旧值,并将更新的新记录添加到列表末尾(所有收集的数据都放入新记录中)。写作时必须更深入一层。
答案 2 :(得分:0)
我个人会将Pandas用于此类内容,特别是DataFrame.append
首先,您将使用pandas.DataFrame.from_csv('filename')
为两个CSV创建一个DataFrame。
然后将DataFrames追加到一起:myDataFrame.append(otherDataframe)
。
最后用to_csv()
输出结果。