【问题标题】:Merge 2 csv files with python用python合并2个csv文件
【发布时间】:2016-05-01 21:25:59
【问题描述】:

我有 2 个 csv 文件如下:

文件1.csv:

Name, Email
Jon, jon@email.com
Roberto, roberto@email.com
Mona, mona@email.com
James, james@email.com

文件2.csv:

Email
mona@email.com
james@email.com

我想要的是没有 File2.csv 的 File1.csv,iex File3.csv(输出)应该如下所示:

文件3.csv:

Name, Email
Jon, jon@email.com
Roberto, roberto@email.com

用 Python 编写代码最简单的方法是什么?

【问题讨论】:

  • File3.csv 恰好是 File1.csv 的子集,那么为什么需要合并?
  • 一种简单的方法是将file2读入一个列表,然后逐行读取file1,并将邮件不在列表中的每一行写入file3。尝试编写代码,如果遇到困难,请发布代码并寻求帮助。
  • 已经回答了很多时间。显示一些可以使用的代码,否则你可能会被标记为重复。

标签: python csv


【解决方案1】:
dont_need_em = []
with open("file2.csv", 'r') as fn:
    for line in fn:
        if not line.startswith("Email"):
            dont_need_em.append(line.rstrip())

fw = open("file3.csv", 'w')

with open("file1.csv", 'r') as fn:
    for line in fn:
        if line.rstrip().split(", ")[1] not in dont_need_em: 
            fw.write(line.rstrip())
fw.close()

应该这样做,但我相信有更简单的解决方案

编辑:创建第三个文件

【讨论】:

  • 请看下面我的回答,我使用的方法基本完全相同
【解决方案2】:

这是一个很好的方法(它与上面的非常相似,但将剩余部分写入文件而不是打印:

Removed = []
with open("file2.csv", 'r') as f2:
    for line in f2:
        if not line.startswith("Email"):
           removed.append(line.rstrip())


with open("file1.csv", 'r') as f1:
    with open("file3.csv", 'w') as f3:
        for line in f1:
            if line.rstrip().split(", ")[1] not in removed:
                f3.write(line)

这是如何工作的: 第一个块将您要过滤的所有电子邮件读取到一个列表中。接下来,第二个块打开您的原始文件并设置一个新文件来写入剩下的内容。它从您的第一个文件中读取每一行并将它们写入第三个文件仅当电子邮件不在您的过滤列表中时

【讨论】:

    【解决方案3】:

    使用 Pandas 你可以做到这一点:

    import pandas as pd
    #Read two files into data frame using column names from first row
    file1=pd.read_csv('File1.csv',header=0,skipinitialspace=True)
    file2=pd.read_csv('File2.csv',header=0,skipinitialspace=True)
    
    #Only return lines in file 1 if the email is not contained in file 2
    cleaned=file1[~file1["Email"].isin(file2["Email"])]
    
    #Output file to CSV with original headers
    cleaned.to_csv("File3.csv", index=False)
    

    【讨论】:

      【解决方案4】:

      如果你在 UNIX 下:

      #! /usr/bin/env python
      import subprocess
      import sys
      
      def filter(input_file, filter_file, out_file):
          subprocess.call("grep -f '%s' '%s' > '%s' " % (filter_file, input_file, out_file), shell=True)
      

      【讨论】:

        【解决方案5】:

        以下应该可以满足您的需求。首先将File2.csv 读入set 要跳过的电子邮件地址。然后逐行读取File1.csv,只写入不在跳过列表中的行:

        import csv
        
        with open('File2.csv', 'r') as file2:
            skip_list = set(line.strip() for line in file2.readlines()[1:])
        
        with open('File1.csv', 'rb') as file1, open('File3.csv', 'wb') as file3:
            csv_file1 = csv.reader(file1, skipinitialspace=True)
            csv_file3 = csv.writer(file3)
            csv_file3.writerow(next(csv_file1))    # Write the header line
        
            for cols in csv_file1:
                if cols[1] not in skip_list:
                    csv_file3.writerow(cols)
        

        这将在File3.csv 中为您提供以下输出:

        Name,Email
        Jon,jon@email.com
        Roberto,roberto@email.com
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-03-18
          • 2012-08-12
          • 1970-01-01
          • 2013-04-22
          相关资源
          最近更新 更多