比较Python中的两个CSV
我正在用Python格式化CSV以获得所需的结果,但我的代码似乎工作不正常 我有以下格式的第一个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,
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:这也很有效。没有声誉来推翻你的答案,抱歉,伙计。