Python 在两个文件中查找相似的列
我正在使用python,我想编写一个代码,它将只比较前两列(0:1),如果另一个文件在第0列和第1列中具有相同的值,那么该行应该合并并写入一个新文件 例如: 或以个人为例: 我现在的代码是这样的,但它并不好Python 在两个文件中查找相似的列,python,comparison,Python,Comparison,我正在使用python,我想编写一个代码,它将只比较前两列(0:1),如果另一个文件在第0列和第1列中具有相同的值,那么该行应该合并并写入一个新文件 例如: 或以个人为例: 我现在的代码是这样的,但它并不好 f1 = open('f1.txt','r') f2 = open('f2.txt','r') f3 = open('f12.txt','w') f1_readlines = f1.readlines() f1_linenum = len(f1_readlines) f2_rea
f1 = open('f1.txt','r')
f2 = open('f2.txt','r')
f3 = open('f12.txt','w')
f1_readlines = f1.readlines()
f1_linenum = len(f1_readlines)
f2_readlines = f2.readlines()
f2_linenum = len(f2_readlines)
i=0
while(i<f1_linenum):
j=0
while(j<f2_linenum):
if(f1_readlines[0:1] == f2_readlines[0:1]):
print(f1_readlines[i])
f12.write(f1_readlines[i])
j = j + 1
i = i + 1
f1.close()
f2.close()
f12.close()
f1=open('f1.txt','r')
f2=打开('f2.txt','r')
f3=打开('f12.txt','w')
f1_readlines=f1.readlines()
f1\u linenum=len(f1\u读线)
f2_readlines=f2.readlines()
f2_linenum=len(f2_readlines)
i=0
而(i你对代码有什么问题
好的…使用while循环不是最好的。您可以这样做:
f1 = open('f1.txt','r')
f1_readlines = f1.readlines()
for ln in f1_readlines:
print ln,
(编辑)此代码:
f1_readlines=[[10, 10, 10], [20, 20, 20], [30, 30, 30]]
f2_readlines=[[20, 20, 25], [30, 30, 11], [25, 25, 55], [44, 44, 58]]
f12=[]
for f1e in f1_readlines:
for f2e in f2_readlines:
if f1e[0]==f2e[0] and f1e[1]==f2e[1]:
f1e.append(f2e[2])
f12.append(f1e)
break
for e in f12:
print e
给出:
[20, 20, 20, 25]
[30, 30, 30, 11]
这里有一个算法,可以处理两个未排序的文件。此算法的优点是只需要内存中的一个文件,并且时间复杂度与输入文件的长度之和成线性关系。换句话说,此算法使用的内存和时间量很小——许多其他算法在r time.(@dede的答案似乎工作得很好,比我的答案简单,但它使用了更多的内存和时间,这对于大型输入文件来说非常明显。)
首先,逐行阅读第一个文件,并从中构建字典。每个键是一行中前两项的元组,对应的值是该行的其余部分。在第二个示例中,生成的字典是
{('Brad', 'Pitt'): 'cherries', ('Angelina', 'Jolie'): 'bred', ('Jack', 'Nicholson'): 'apples', ('Nicole', 'Kidman'): 'cucumber'}
然后创建一个空的输出文件,并逐行读取第二个输入文件。对于每一行,您可以查看字典中是否有前两项。如果有,请将所需的行打印到输出文件中。如果没有,则不处理该行
然后,您主要使用的内存是字典。您只对每个输入文件进行了一次逐行检查,因此速度很快。这种方法的主要可能缺点是,输出文件的顺序与第二个输入文件中的项目顺序相同,这是第二个示例中的顺序。如果您希望第一个输入文件的顺序相同相反,只需交换两个输入文件的用法
这是我从该算法中得到的代码。此版本假设每个输入行正好有三个由空格或制表符分隔的项。如果行中的“第三项”可能包含空格或制表符,则代码需要稍微复杂一些。使用示例输入文件,此代码的结果正是您想要的
def similar_columns(filenameinput1, filenameinput2, filename_output):
"""Find the similar columns in two files.
This assumes each line has exactly three items.
"""
# Build a dictionary of the items in the first input file
items_dict = {}
with open(filenameinput1, 'r') as inputfile1:
for line in inputfile1:
col0, col1, oldcolrest = line.split()
items_dict[(col0, col1)] = oldcolrest
# Compare the items in the second input file, saving matches
with open(filenameinput2, 'r') as inputfile2, \
open(filename_output, 'w') as outputfile:
for line in inputfile2:
col0, col1, newcolrest = line.split()
oldcolrest = items_dict.get((col0, col1), None)
if oldcolrest is not None:
outputfile.write('{} {} {} {}\n'.format(
col0, col1, oldcolrest, newcolrest))
similar_columns('f1.txt', 'f2.txt', 'f12.txt')
similar_columns('shop1.txt', 'shop2.txt', 'total.txt')
我试图用一种天真的方式来解决它
f1 = open('f1.txt','r')
f2 = open('f2.txt','r')
f3 = open('fusion.txt','w')
# read f1 lines from file
f1_readlines = f1.readlines()
# get f1 length
f1_linenum = len(f1_readlines)
# read f2 lines from file
f2_readlines = f2.readlines()
# get f2 length
f2_linenum = len(f2_readlines)
for f1_line in f1_readlines:
arr1 = f1_line.split(" ")
c11 = arr1[0]
c12 = arr1[1]
for f2_line in f2_readlines:
arr2 = f2_line.split(" ")
c21 = arr2[0]
c22 = arr2[1]
if((c11 == c21) & (c12 == c22)):
output = [c11,c12]
for c in arr1[2:]:
s = c.strip("\n")
output.append(s)
for c in arr2[2:]:
s = c.strip("\n")
output.append(s)
for num in output[0:len(output)-1]:
f3.write(num)
f3.write(" ")
f3.write(output[len(output)-1])
f3.write("\n")
f1.close()
f2.close()
f3.close()
f1
f2
融合
10 10 25 55
56 66 55 55 99
78 56 56 7 56
77 77 77 77
希望这能解决问题:)这些文件是按任何方式排序的吗?(您的示例文件f2
似乎没有排序。)文件的顺序(输入或输出)有关系吗?当文件按要比较的项目排序时,比较行要容易得多。是的,文件排序有一定意义,但行号不同。输出应该是f1+f2(没有前两列)。我必须将f2的第一行与f1中的所有行进行比较,然后是第二行、第三行,依此类推……文件是否采用特定格式,即CSV或CTV或定长列?@RehanAzher:第二个示例显示列不是定长的。我的答案适用于空格分隔或制表符分隔的文件,因为Python的split
方法处理它们的方式是相同的。@RoryDaulton我没有质疑任何解决方案,只要这些解决方案可行。如果每个文件都有1M条记录,那么它的性能会如何?我的代码没有将f2行与所有f1行进行比较,我想,它只是逐行比较抱歉,我是编程新手。什么是f1e,f2e?没什么特别的…简单的循环变量。在for循环之间插入print语句,查看它们在每次迭代中得到的值。它们仅用于循环中。他们在每次迭代中得到一个新值。请看:这似乎是与dede的答案相同的算法。这个答案如何更好?
10 10 55
77 77 77
20 22 20
11 13 11
2 23 23
56 66 55 99
78 56 56
10 10 25 55
56 66 55 55 99
78 56 56 7 56
77 77 77 77