合并两个CSV文件保留重复项

时间:2016-09-28 16:00:04

标签: python python-3.x csv merge

我正在尝试合并两个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

3 个答案:

答案 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()输出结果。

全部放在一起: Code snippet