我有2份txt文档,a.txt 和 b.txt。每份文档都有511万多行的数据。
我想从a.txt文档里,找出b.txt 所没有的数据
下面的表格是示例
每行开头是一个8位数的数字,叫做ssid,长度都是8位,固定的
只要比较2份文档的ssid就行了。ssid后面的内容不需要做比较
表头 |
---|
15085237,000018718299,沙粒中的宇宙:微电影叙事学研究,尤达著,北京:中国传媒大学出版社,2019.10,252,9787565726125 |
15063264,000019466090,基诺山 太阳的手印,段瑞秋,昆明:云南人民出版社,2021.10,366,9787222204270 |
15006671,000019379527,难产 第2版,刘兴会,漆洪波作,北京:人民卫生出版社,2021.06,728,9787117315098 |
14821405,000018694741,内幕交易的多副面孔,宁荣,北京:经济科学出版社,2019.01,322,9787521807776 |
比如a.txt 有15085237这个ssid,b.txt 没有15085237,那就把15085237这一行,保存到c.txt 里,整行都要保存
另一种方案,比如a.txt 和b.txt 都有15063264,那就把a.txt 里的15063264整行数据都删了,b.txt里的不用删
2种方案不知道哪种更好
我需要一个python代码实现这个功能,能实现其中一个方案就行了
电脑里有python 3.8.10 环境,不过我只学了一些python的基础语法,不知道怎么写
如果你只要比较,可以用现成的 BeyondCompare,或者 WinDiff,没必要自己写了。
第一种比较好,更新数据的原则是:尽可能不要修改元数据。
首先比较指定元数据列的话,可以直接把 a.txt 和 b.txt 中的 ssid 列取出来,通过集合的运算,把 ssid 在 a.txt 中不在 b.txt 中的取出来,然后通过集合获取差异的ssid,最后再把想要的行存取到 c.txt 文件中即可。
## a.txt
ssid,code,name,author,publish,time,price,id #自己写的标头行
15085237,000018718299,沙粒中的宇宙:微电影叙事学研究,尤达著,北京:中国传媒大学出版社,2019.10,252,9787565726125
15063264,000019466090,基诺山 太阳的手印,段瑞秋,昆明:云南人民出版社,2021.10,366,9787222204270
15006671,000019379527,难产 第2版,刘兴会,漆洪波作,北京:人民卫生出版社,2021.06,728,9787117315098
14821405,000018694741,内幕交易的多副面孔,宁荣,北京:经济科学出版社,2019.01,322,9787521807776
###python代码
import pandas as pd
#用 read_csv,是由于文件中都是用逗号分割的,skiprows--跳过表头
df_a = pd.read_csv('a.txt',header=None,skiprows=[0])
result_a = set( df_a[0].tolist() ) #{'15085237', '15063264', '14821405', '15006671'}
##只读取 ssid 列,usecols--指定只读取指定的列,
df_b = pd.read_csv('b.txt',header=None,usecols=[0],skiprows=[0])
result_b = set( df_b[0].tolist() )
#获取差异的ssid
result = list(result_a - result_b)
#差异的数据
df_c = df_a[ df_a[0].isin(result) ]
pd.DataFrame( df_c,columns=[....'把文件中的表头放在这里'] ).to_csv('c.txt',index=False)
【以下回答由 GPT 生成】
# 导入所需的模块
import csv
def compare_documents(a_file, b_file, c_file):
# 读取a.txt的数据
with open(a_file, 'r') as file_a:
a_data = set(line.split(',')[0] for line in file_a)
# 读取b.txt的数据,同时保存不同的数据到c.txt
with open(b_file, 'r') as file_b, open(c_file, 'w') as file_c:
csv_writer = csv.writer(file_c)
for line in file_b:
ssid = line.split(',')[0]
if ssid not in a_data:
csv_writer.writerow(line)
print("比较完毕,结果已保存到c.txt")
# 主程序
a_file = 'a.txt'
b_file = 'b.txt'
c_file = 'c.txt'
compare_documents(a_file, b_file, c_file)
代码解释:
首先导入了csv
模块,用于读写csv文件。
然后定义了一个名为compare_documents
的函数,该函数接受三个参数:a_file
,b_file
和c_file
,分别表示a.txt
,b.txt
和c.txt
的文件路径。
函数内部首先使用with open(a_file, 'r') as file_a
语句打开a.txt
文件,并读取其中的数据。通过使用列表推导式和split
方法,可以获取每行数据的ssid,并将其添加到一个集合中(使用set进行存储,方便后续的数据比较)。
接下来,使用with open(b_file, 'r') as file_b, open(c_file, 'w') as file_c
语句同时打开b.txt
和c.txt
文件,其中b.txt
用于读取数据,c.txt
用于保存不同的数据。同时使用csv.writer
来进行写入文件c.txt
。
在文件b.txt
的循环中,使用split
方法获取每行数据的ssid,并通过判断ssid是否在集合a_data
中来检查是否存在于a.txt
文档中。如果ssid不在集合中,说明该行数据在b.txt
中没有对应的数据。
在检查结果为不同的情况下,使用csv_writer.writerow
将整行数据写入到文件c.txt
中。
最后输出提示信息和关闭文件,表示比较完成。
注意事项:
该代码适用于处理数据量较小的情况,如果面对非常大的文档,可能会导致内存消耗较大。
如果遇到数据格式不一致的情况,需要根据实际情况进行调整。
请确保文件路径正确,文档的编码格式正确以避免乱码问题。
求差集输出出来
方案一:
注意:文件比较大的话比较耗内存
a_dict = {}
b_dict = {}
with open('a.txt', 'r', encoding='utf8') as file:
line = file.readline()
while line:
line = line.strip()
ls = line.split(',')
if len(ls) > 1:
a_dict[ls[0]] = line
line = file.readline()
with open('b.txt', 'r', encoding='utf8') as file:
line = file.readline()
while line:
line = line.strip()
ls = line.split(',')
if len(ls) > 1:
b_dict[ls[0]] = line
line = file.readline()
a_set = set(a_dict.keys())
b_set = set(b_dict.keys())
c_set = a_set.difference(b_dict)
with open('c.txt', 'w', encoding='utf8') as file:
for key in c_set:
file.write(a_dict[key] + '\n')
print('done')