注册 登录
编程论坛 Python论坛

[求助]有关文本文件差集的操作

阿智兄 发布于 2021-03-19 13:37, 3082 次点击
有两个文本文件A.TXT,B.TXT,要将A文件中冒号后面部分含有B的那部分数据去掉后生成新文件C.TXT,例如:
A.TXT数据如下:
A8A13A14A17A38A40:01,02,03,04,09,23
A1A17A38A40A62A66:01,02,03,05,08,17
A1A20A23A42A62A65:01,02,03,05,13,17
A1A3A14A23A30A38:01,02,03,05,13,25
A2A20A38A40A45A67:01,02,03,05,13,29
A1A23A31A42A43A65:01,02,03,05,13,33
A1A3A13A31A36A40:01,02,03,05,14,23
A3A20A32A38A47A57:01,02,03,06,07,24
A1A35A37A42A45A57:01,02,03,06,08,22
A1A8A33A35A42A62:01,02,03,06,14,27
A3A37A38A49A50A76:01,02,03,06,18,21
A3A6A32A35A47A57:01,02,03,06,19,24
A3A19A26A35A36A67:01,02,03,07,10,15

B.TXT数据如下:
A8A13A14A17A38A40:01,02,03,04,09,23
A1A17A38A40A62A66:01,02,03,05,08,17
A1A20A23A42A62A65:01,02,03,05,13,17
A1A3A14A23A30A38:01,02,03,05,13,25
A2A20A38A40A45A67:01,02,03,05,13,29
A1A23A31A42A43A65:01,02,03,05,13,33
A1A3A13A31A36A40:01,02,03,05,14,23
A3A20A32A38A47A57:01,02,03,06,07,24
A1A35A37A42A45A57:01,02,03,06,08,22

生成的C.TXT如下:
A1A8A33A35A42A62:01,02,03,06,14,27
A3A37A38A49A50A76:01,02,03,06,18,21
A3A6A32A35A47A57:01,02,03,06,19,24
A3A19A26A35A36A67:01,02,03,07,10,15

帮忙看看怎么修改?
程序代码:

def test():
    new_text_path="output.txt"
    oldText = open("txt002.txt","r")
    newText = open("txt001.txt","r")
    new_file_path=open("output.txt","w")

 
    for oldline in oldText:
        newText = open("txt001.txt", "r")
        for newline in newText:
            new_text = [ i for i in oldText if i not in newText ]
            new_file_path.write(new_text)  #从新写入到新的文件
if __name__ == '__main__':
    test()


[此贴子已经被作者于2021-3-19 15:22编辑过]

21 回复
#2
zyb1593572021-03-19 21:10
f1=open("A.txt", "r")
f2=open("B.txt", "r")
A=set(f1.read().split("\n"))
B=set(f2.read().split("\n"))
with open("C.txt", "w") as c:
    for i in (A-B):
        c.write(i+"\n")
f1.close()
f2.close()        
#3
zyb1593572021-03-19 21:56
#按你的意思写一个,但效率不如上面的.
f1=open("A.txt", "r")
f2=open("B.txt", "r")
A=f1.readlines() #
B=f2.read()
with open("C.txt", "w") as c:
    for i in A:
        if i.strip("\n") not in B: #A的i行不在B.txt里.
           c.write(i)
f1.close()
f2.close()      
#4
阿智兄2021-03-19 22:43
回复 3楼 zyb159357
谢谢你的回复。忘了把冒号前面的部分改为不相同的了,并且是乱序的。重新改了下,实际是这样的(只要冒号后面那部分相同的就去除):
A.TXT数据如下:
A1A17A38A40A62A66:01,02,03,05,08,17
A1A20A23A42A62A65:01,02,03,05,13,17
A1A23A31A42A43A65:01,02,03,05,13,33
A1A35A37A42A45A57:01,02,03,06,08,22
A1A3A13A31A36A40:01,02,03,05,14,23
A1A3A14A23A30A38:01,02,03,05,13,25
A1A8A33A35A42A62:01,02,03,06,14,27
A2A20A38A40A45A67:01,02,03,05,13,29
A3A19A26A35A36A67:01,02,03,07,10,15
A3A20A32A38A47A57:01,02,03,06,07,24
A3A37A38A49A50A76:01,02,03,06,18,21
A3A6A32A35A47A57:01,02,03,06,19,24
A8A13A14A17A38A40:01,02,03,04,09,23

B.TXT数据如下:
A1A23A31A42A43A65:01,02,03,05,13,33
A1A25A23A42A67A65:01,02,03,05,13,17
A1A3A14A23A30A38:01,02,03,05,13,25
A2A20A38A42A45A67:01,02,03,05,13,29
A3A17A38A40A62A66:01,02,03,05,08,17
A3A20A32A35A47A57:01,02,03,06,07,24
A3A35A39A42A45A67:01,02,03,06,08,22
A7A3A13A31A37A40:01,02,03,05,14,23
A8A13A14A17A38A40:01,02,03,04,09,23

生成的C.TXT如下:
A1A8A33A35A42A62:01,02,03,06,14,27
A3A37A38A49A50A76:01,02,03,06,18,21
A3A6A32A35A47A57:01,02,03,06,19,24
A3A19A26A35A36A67:01,02,03,07,10,15

下面是我改过的代码,但也没得到预期结果:
程序代码:


 f3 = open("output.txt", "w")            

 with open('txt001.txt') as f1:
  for line1 in f1:
   line1.strip('\n').split(':')[1])  #取冒号后面部分
  

 with open('txt002.txt') as f2:
  for line2 in f2:
   line2.strip('\n').split(':')[1])  #取冒号后面部分
  for i in line1:
   if i not in line2:

 print(i,end="\n",file=f3)

 f3.close



[此贴子已经被作者于2021-3-19 23:54编辑过]

#5
zyb1593572021-03-20 00:07
f1=open("A.txt", "r")
f2=open("B.txt", "r")
A=f1.readlines() #
B=f2.read()
with open("C.txt", "w") as c:
    for i in A:
        if i.strip("\n").split(":")[1] not in B: #A的i行后半部分不在B.txt里.
           c.write(i)
f1.close()
f2.close()      
#6
阿智兄2021-03-20 00:37
回复 5楼 zyb159357
谢谢,刚才测试时文件数据出错导致结果不对,现在找到原因了。
这样的情况怎么办?
如果有多个文件A,B,C,D,E,F...都是跟A做差集运算。相当于A-B-C-D-E-F=?

[此贴子已经被作者于2021-3-20 01:00编辑过]

#7
zyb1593572021-03-20 00:47
我把你上面的数据代入, 输出的结果和你的预期一样
#8
zyb1593572021-03-20 00:56
f1=open("A.txt", "r")
f2=open("B.txt", "r")
A=f1.readlines() #
B=f2.read()
with open("C.txt", "w") as c:
    for i in A:
        if i.strip("\n").split(":")[1].strip() not in B: #A的i行后半部分不在B.txt里.
        #试试再加一个strip()防止多余空格.
           c.write(i)
f1.close()
f2.close()      
#9
阿智兄2021-03-20 01:01
回复 8楼 zyb159357
确实是空格的问题。
这样的情况怎么办?
如果有多个文件A,B,C,D,E,F...都是跟A做差集运算。相当于A-B-C-D-E-F=?
#10
zyb1593572021-03-20 01:24
f1=open("A.txt", "r")
f2=open("B.txt", "r")
f3=open('D.txt', "r")
f4=open('E.txt', "r")
#f5,f6.....
A=f1.readlines() #
B=f2.read()+f3.read()+f4.read()  #加f5.read(),f6.....合并文件内容.
with open("C.txt", "w") as c:
    for i in A:
        if i.strip("\n").split(":")[1] not in B: #A的i行后半部分不在B.txt里.
           c.write(i)
f1.close()
f2.close()      
#11
阿智兄2021-03-20 02:28
回复 10楼 zyb159357
谢谢回复,这个方法跟手动把其他文件合并后再跟A做差集是一样的,非常慢。
如果每得到的一个差集再跟下一个做差集运算该怎么做呢?
#12
zyb1593572021-03-20 14:37
#这样试试效果.
def one_data(file):#提取单一文件关注数据  
    for i in open(file):
        yield i.split(":")[1].strip()
            
def Multiple_Data(*files):#提取多个文件关注数据
    for i in files:
        for j in one_data(i):
            yield j

def dataset(*files): #多文件并集
    return set(Multiple_Data(*files))

f1=open("A.txt", "r")
A=f1.readlines()
lst=('B.txt' , 'C.txt' , 'D.txt' , 'E.txt')
B=dataset(*lst)
#B=dataset('B.txt' , 'C.txt' , 'D.txt' , 'E.txt')
with open("new.txt", "w") as c:
    for i in A:
        if i.strip("\n").split(":")[1] not in B: #A的i行后半部分不在B.txt里.
           c.write(i)
f1.close()



[此贴子已经被作者于2021-3-20 14:54编辑过]

#13
阿智兄2021-03-20 15:13
回复 12楼 zyb159357
谢谢回复,
这个意思是A-(B+C+D+E+F),主要是并集后的文件很大了,效率上很低。
如果做成这样
A-B=临时文件M1
临时文件M1-B=临时文件M3
临时文件M3-C=临时文件M4
临时文件M4-D=临时文件M5
...
这样效率会越来越高。
这样不论文件夹中有多少文件效率都不会低。

[此贴子已经被作者于2021-3-20 15:15编辑过]

#14
zyb1593572021-03-20 15:14
#这个效率应该不错.
def one_data(file):#提取单一文件关注数据  
    for i in open(file):
        yield i.split(":")[1].strip()
            
def Multiple_Data(*files):#提取多个文件关注数据
    for i in files:
        for j in one_data(i):
            yield j

def dataset(*files): #多文件并集
    return set(Multiple_Data(*files))

f1=open("A.txt", "r")
A=f1.readlines()
A_set=dataset("A.txt")
lst=('B.txt' , 'C.txt' , 'D.txt' , 'E.txt')
B=dataset(*lst)
#B=dataset('B.txt' , 'C.txt' , 'D.txt' , 'E.txt')
with open("new.txt", "w") as c:
    B=A_set - B
    for i in A:
        if i.strip("\n").split(":")[1] in B:
           c.write(i)
f1.close()
#15
阿智兄2021-03-20 15:30
回复 14楼 zyb159357
谢谢回复。
由于B,C,D,E,F...每个文件都装有50万行左右的数据,并起来后再跟A(该文件也有10几万行数据)比较,估计真的很难看到结果。
#16
zyb1593572021-03-20 15:36
回复 14楼 zyb159357
晚点按你的思路搞一下,现在要忙。
#17
zyb1593572021-03-20 18:26
以下是引用阿智兄在2021-3-20 15:13:21的发言:

谢谢回复,
这个意思是A-(B+C+D+E+F),主要是并集后的文件很大了,效率上很低。
如果做成这样
A-B=临时文件M1
临时文件M1-B=临时文件M3
临时文件M3-C=临时文件M4
临时文件M4-D=临时文件M5
...
这样效率会越来越高。
这样不论文件夹中有多少文件效率都不会低。


#按上面意思做的.  但觉得效率可能没有上面那个高效.
def _filter(A_data,path_file):
    f=open(path_file, "r")
    B=f.read()
    for i in A_data:
        if i.strip("\n").split(":")[1] not in B:
            yield i   
    f.close()


f1=open("A.txt", "r")
A_data=f1.readlines()
for path_file in ("B.txt" , "C.txt"): # D.txt,E.txt.....
    A_data=_filter(A_data,path_file)
with open("./abcdf/save.txt","w") as f:
    for i in  A_data:
        f.write(i)
f1.close()
#18
阿智兄2021-03-20 19:51
回复 17楼 zyb159357
谢谢你的再次耐心回复。
我分析了代码,发现思路跟下面这个思路有所出入。
这行代码如果改为自动逐个载入文件夹中除了A以外的每个文件,跟相应的每次差集后的临时文件再做差集运算,那么临时文件将会越来越小,速度必然会越来越快。
for path_file in ("B.txt" , "C.txt"): # D.txt,E.txt.....

效果如下:
A-B=临时文件M1  (30-4=26)
临时文件M1-B=临时文件M3   (26-7=19)
临时文件M3-C=临时文件M4   (19-5=12)
临时文件M4-D=临时文件M5    (12-4=8)
...


[此贴子已经被作者于2021-3-20 19:53编辑过]

#19
zyb1593572021-03-20 21:21
以下是引用阿智兄在2021-3-20 19:51:56的发言:

谢谢你的再次耐心回复。
我分析了代码,发现思路跟下面这个思路有所出入。
这行代码如果改为自动逐个载入文件夹中除了A以外的每个文件,跟相应的每次差集后的临时文件再做差集运算,那么临时文件将会越来越小,速度必然会越来越快。
for path_file in ("B.txt" , "C.txt"): # D.txt,E.txt.....

效果如下:
A-B=临时文件M1  (30-4=26)
临时文件M1-B=临时文件M3   (26-7=19)
临时文件M3-C=临时文件M4   (19-5=12)
临时文件M4-D=临时文件M5    (12-4=8)
...


#估计你没读懂代码, A_data就是临时列表,越来越少!
#20
阿智兄2021-03-20 22:55
回复 19楼 zyb159357
谢谢你的再次耐心回复。
这段代码改为自动读取当前文件夹中的文件该怎么改呢?
for path_file in ("B.txt" , "C.txt"): # D.txt,E.txt.....
#21
zyb1593572021-03-20 23:55
以下是引用阿智兄在2021-3-20 22:55:28的发言:

谢谢你的再次耐心回复。
这段代码改为自动读取当前文件夹中的文件该怎么改呢?
for path_file in ("B.txt" , "C.txt"): # D.txt,E.txt.....

import os
def path():
    for i in os.listdir("./"): #获取当前文件夹内的全部文件名.
        if (".txt" in i) and ('A.txt' not in i): #选取.txt文件,但不包括A.txt.
             yield i
for path_file in path():
    pass
#22
阿智兄2021-03-21 01:14
回复 21楼 zyb159357
非常感谢你的多次耐心回复。
问题解决了。


[此贴子已经被作者于2021-3-21 14:54编辑过]

1