csv 有没有更快的方法逐行阅读两个文件,然后在另一行的末尾添加一行?

9ceoxa92  于 2022-12-06  发布在  其他
关注(0)|答案(3)|浏览(98)

所以我问题是:
我有两个CSV文件,每个文件有大约500 000行。
文件1如下所示:

ID|NAME|OTHER INFO
353253453|LAURENT|STUFF 1
563636345|MARK|OTHERS
786970908|GEORGES|THINGS

文件2如下所示:

LOCATION;ID_PERSON;PHONE
CA;786970908;555555
NY;353253453;555666

因此,我需要做的是查找ID相同的行,并将文件2中的行添加到新文件中文件1中对应行的末尾,如果没有对应的ID,则添加空列,如下所示:

ID;NAME;OTHER INFO;LOCATION;ID_PERSON;PHONE
353253453;LAURENT;STUFF 1;NY;353253453;555666
563636345;MARK;OTHERS;;;
786970908;GEORGES;THINGS;CA;786970908;555555

文件1是主要的,如果这是有意义的。
问题是我已经找到了一个解决方案,但它需要太长的时间,因为对于文件1的每一行,我循环通过文件2。
下面是我的代码:

input1 = open(filename1, 'r', errors='ignore')
input2 = open(filename2, 'r', errors='ignore')
output = open('result.csv', 'w', newline='')

for line1 in input1:
    line_splitted = line1.split("|")
    id_1 = line_splitted[0]
    index = 0
    find = False
    for line2 in file2:
        file2_splitted = line2.split(";")
        if id_1 in file2_splitted[1]:
                output.write((";").join(line1.split("|"))+line2)
                find = True
                file2.remove(line2)
                break
         index+=1
         if index == len(file2) and find == True:
                output.write((";").join(line1.split("|")))
                for j in range(nbr_col_2):
                    output.write(";")
                output.write("\n")

所以我想知道是否有更快的方法来做到这一点,或者我是否必须耐心等待,因为现在20分钟后,只写了20000行...

b4lqfgs4

b4lqfgs41#

首先逐行读取file2,以建立lookup指令。
然后逐行读取file1,在dict中查找ID键,构建输出行并写入输出文件。
这是一个复杂度为O(n)的过程,只有dict会消耗一点内存,所有的文件处理都是基于流的。

with open("file2.txt") as f:
    lookup = {}
    f.readline()  # skip header
    while True:
        line = f.readline().rstrip()
        if not line:
            break
        fields = line.split(";")
        lookup[fields[1]] = line

with open("file1.txt") as f, open("output.txt", "w") as out:
    f.readline()  # skip header
    out.write("ID;NAME;OTHER INFO;LOCATION;ID_PERSON;PHONE\n")
    while True:
        line_in = f.readline().rstrip()
        if not line_in:
            break
        fields = line_in.split("|")
        line_out = ";".join(fields)
        if found := lookup.get(fields[0]):
            line_out += ";" + found
        else:
            line_out += ";;;"
        out.write(line_out + "\n")
ca1c2owp

ca1c2owp2#

正如Alex在他的评论中指出的,你可以使用Pandas合并这两个文件。

import pandas as pd

# Load files
file_1 = pd.read_csv("file_1.csv", index_col=0, delimiter="|")
file_2 = pd.read_csv("file_2.csv", index_col=1, delimiter=";")

# Rename PERSON_ID as ID
file_2.index.name = "ID"

# Merge files
file_3 = file_1.merge(file_2, how="left", on="ID")
file_3.to_csv("file_3.csv")

使用示例file_3.csv看起来如下所示:

ID,NAME,OTHER INFO,LOCATION,PHONE
353253453,LAURENT,STUFF 1,NY,555666.0
563636345,MARK,OTHERS,,
786970908,GEORGES,THINGS,CA,555555.0

额外

顺便说一句,如果你不熟悉Pandas,这是一个很棒的入门课程:Learn Pandas Tutorials

w51jfk4q

w51jfk4q3#

您可以创建索引以防止每次都遍历file2。通过从file2创建一个字典并通过调用其索引检索它的每个相关项来实现这一点。

file1 = open(filename1, 'r', errors='ignore')
file2 = open(filename2, 'r', errors='ignore')
output = open('result.csv', 'w', newline='')

indexed_data = {}
for line2 in file2.readlines()[1:]:
    data2 = line2.rstrip('\n').split(";")
    indexed_data[data2[1]] = {
        'Location': data2[0],
        'Phone': data2[2],
    }

output.write('ID;NAME;OTHER INFO;LOCATION;ID_PERSON;PHONE\n')

for line1 in file1.readlines()[1:]:
    data1 = line1.rstrip('\n').split("|")
    if data1[0] in indexed_data:
        output.write(f'{data1[0]};{data1[1]};{data1[2]};{indexed_data[data1[0]]["Location"]};{data1[0]};{indexed_data[data1[0]]["Phone"]}\n')
    else:
        output.write(f'{data1[0]};{data1[1]};{data1[2]};;;\n')

相关问题