Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
比较Python中的两个CSV_Python - Fatal编程技术网

比较Python中的两个CSV

比较Python中的两个CSV,python,Python,我正在用Python格式化CSV以获得所需的结果,但我的代码似乎工作不正常 我有以下格式的第一个CSV文件: 2,a 1,a 4,a 5,a 3,a 1,a 3,b 2,b 1,a 1,a,123 1,a,234 2,a,456 2,b,345 3,a,789 3,b,232 4,a,987 2,a,456 1,a,123 4,a,987 5,a 3,a,789 1,a,234 3,b,232 2,b,345 1,a 格式为的第二个CSV文件: 2,a 1,a 4,a 5,a 3,a 1,

我正在用Python格式化CSV以获得所需的结果,但我的代码似乎工作不正常

我有以下格式的第一个CSV文件:

2,a
1,a
4,a
5,a
3,a
1,a
3,b
2,b
1,a
1,a,123
1,a,234
2,a,456
2,b,345
3,a,789
3,b,232
4,a,987
2,a,456
1,a,123
4,a,987
5,a
3,a,789
1,a,234
3,b,232
2,b,345
1,a
格式为的第二个CSV文件:

2,a
1,a
4,a
5,a
3,a
1,a
3,b
2,b
1,a
1,a,123
1,a,234
2,a,456
2,b,345
3,a,789
3,b,232
4,a,987
2,a,456
1,a,123
4,a,987
5,a
3,a,789
1,a,234
3,b,232
2,b,345
1,a
由于第一个CSV文件未排序,因此第二个CSV文件相对于第一列按递增顺序排序

我希望输出的格式为:

2,a
1,a
4,a
5,a
3,a
1,a
3,b
2,b
1,a
1,a,123
1,a,234
2,a,456
2,b,345
3,a,789
3,b,232
4,a,987
2,a,456
1,a,123
4,a,987
5,a
3,a,789
1,a,234
3,b,232
2,b,345
1,a
如果在第二个CSV文件中找不到第一个CSV文件组合,例如,如果第二个CSV文件中没有
5,则只打印
5,在其相应位置打印一个
。第一个CSV文件包含许多重复项,而在第二个CSV文件中,每一行都是唯一的

这是我的密码

for (num,alpha) in first_csv:
    value_found = True
    for (num1,alpha1,num2) in second_csv:
        if (num == num1 and alpha == alpha1):
            csv_out +=  str(num) + ',' + str(alpha) + ',' + str(number)
            value_found = False
    if value_found:
        count+=1
        if count == 1:
            csv_out += str(num) + ',' + str(alpha)
first_csv和second_csv是我在读取csv文件和代码后创建的元组:

with open('first_csv.csv') as f:
    f.readline()
    first_csv = tuple(csv.reader(f, delimiter=','))


with open('second_csv.csv') as f:
    f.readline()
    second_csv = tuple(csv.reader(f, delimiter=','))

但是它没有打印所需的输出,我哪里做错了?

这应该可以解决问题。请注意,对于第一个csv上的每次迭代,最坏的情况是它必须迭代到第二个csv文件中剩余数据的末尾(如果匹配,将弹出行)

output.csv

2,a,456
1,a,123
4,a,987
5,a
3,a,789
1,a,234
3,b,232
2,b,345
1,a

这会将第二个文件中的
num2
值收集到s的字典中。找到匹配项后,将使用
deque.popleft
删除匹配项,使每个匹配项只使用一次,顺序与在第二个文件中出现的顺序相同

from collections import defaultdict, deque

with open('second_csv.csv') as f:
    next(f) #skip header
    dic = defaultdict(deque)
    for num1,alpha1,num2 in csv.reader(f, delimiter=','):
        dic[num1, alpha1].append(num2)

with open('first_csv.csv') as f, open('out.csv', 'wb') as fout:
    next(f) #skip header
    csv_out = csv.writer(fout)
    for num,alpha in csv.reader(f, delimiter=','):
        try:
            num2 = dic[num,alpha].popleft()
            csv_out.writerow([num,alpha,num2])
        except IndexError:
            csv_out.writerow([num,alpha])
  • deque
    保留通过
    append
    添加和通过
    popleft
    删除的项目顺序
  • dict通过可以是元组的键进行快速查找
  • defaultdict(deque)
    是一种
    dict
    ,当您访问缺少的密钥时,它会自动创建一个空的
    deque
    ,因此您可以直接将
    附加到它

您是否考虑过使用SQLite将数据存储到两个表中,然后对这两个表执行联接操作以获得所需的结果?仅用Python将其束缚在一起会很快变得痛苦。@makoto您有可以做到这一点的查询吗,我不擅长数据库。示例表明,第二个文件中的每个匹配项只使用一次——第三个
1,一个
不匹配。您能更详细地讨论这个要求吗?@janneKarila作为第三个1,a在第二个csv文件中没有匹配项,所以它只是放在第一个csv文件的相对位置。第三个条目1,a与第二个csv文件中的任何内容都不匹配,因此它是空的,并保持在第一个csv文件的正确位置。@Makoto我进行了查询,但最终它会自动对第一列的结果进行排序,我不知道为什么。我正在使用POSTGRES。我希望输出的顺序与第一个csv文件的顺序相同。谢谢,我知道这会占用您一些时间,我是stackoverflow新手,所以我没有理由对您的答案投赞成票,我这是我第一次看到您使用的东西,请您说明一下,让我知道我做错了什么。再次感谢。@user3218088您的方法中的主要问题是您没有跟踪匹配。使用元组保存第二个csv会使查找变得不必要的困难,并且不允许删除匹配项。谢谢Steinar:这也很有效。没有声誉来推翻你的答案,抱歉,伙计。