Python 在两个文件中查找相似的列

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

我正在使用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_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