使用 Python 字典在 Python 中合并 CSV 文件

Posted

技术标签:

【中文标题】使用 Python 字典在 Python 中合并 CSV 文件【英文标题】:Merge CSV files in Python using Python Dictionary 【发布时间】:2012-11-23 22:43:53 【问题描述】:

您好,我正在尝试根据公共列或主键合并两个 CSV 文件中的特定字段来创建一个新的 CSV 文件。我曾尝试在 powershell 中做同样的事情,它工作但完成过程非常慢 - 合并 5000+ 行文件超过 30 分钟,所以在 Python 中尝试这个。我是新人,所以请放轻松。

所以两个文件是 infile.csv 和 checkfile.csv,并且创建的输出文件中的列将基于 infile.csv 中的列。该代码检查 checkfile.csv 中的值,创建 outfile.csv,从 infile.csv 复制列,并需要根据 checkfile.com 中的相应值重写两个字段的值。以下是详细内容

infile.csv -

"StockNumber","SKU","ChannelProfileID","CostPrice"
"10m_s-vid#APTIIAMZ","2VV-10",3746,0.33
"10m_s-vid#CSE","2VV-10",3746,0.98
"1RR-01#CSE","1RR-01",3746
"1RR-01#PCAWS","1RR-01",3746,
"1m_s-vid_ext#APTIIAMZ","2VV-101",3746,0.42

检查文件.csv

ProductCode, Description, Supplier, CostPrice, RRPPrice, Stock, Manufacturer, SupplierProductCode, ManuCode, LeadTime
2VV-03,3MTR BLACK SVHS M - M GOLD CABLE - B/Q 100,Cables Direct Ltd,0.43,,930,CDL,2VV-03,2VV-03,1
2VV-05,5MTR BLACK SVHS M - M GOLD CABLE - B/Q 100,Cables Direct Ltd,0.54,,1935,CDL,2VV-05,2VV-05,1
2VV-10,10MTR BLACK SVHS M - M GOLD CABLE - B/Q 50,Cables Direct Ltd,0.86,,1991,CDL,2VV-10,2VV-10,1

我得到的 outfile.csv 是 -

StockNumber,SKU,ChannelProfileID,CostPrice
10m_s-vid#APTIIAMZ,2VV-10,"(' ',)", 
10m_s-vid#CSE,2VV-10,"(' ',)", 
1RR-01#CSE,1RR-01,"(' ',)", 
1RR-01#PCAWS,1RR-01,"(' ',)", 
1m_s-vid_ext#APTIIAMZ,2VV-101,"(' ',)", 

但我需要的 outfile.csv 是 -

StockNumber,SKU,ChannelProfileID,CostPrice
10m_s-vid#APTIIAMZ,2VV-10,1991,0.86  
10m_s-vid#CSE,2VV-10,1991,0.86   
1RR-01#CSE,1RR-01
1RR-01#PCAWS,1RR-01          
1m_s-vid_ext#APTIIAMZ,2VV-101

最后是代码 -

import csv

with open('checkfile.csv', 'rb') as checkfile:
    checkreader = csv.DictReader(checkfile)

    product_result = dict(
        ((v['ProductCode'], v[' Stock']), (v['ProductCode'], v[' CostPrice']))  for v in checkreader
    )

with open('infile.csv', 'rb') as infile:
    with open('outfile.csv', 'wb') as outfile:
        reader = csv.DictReader(infile)

        writer = csv.DictWriter(outfile, reader.fieldnames)
        writer.writeheader()

        for item in reader:
            result = product_result.get(item['SKU'], " ")

            item['ChannelProfileID'] = result,
            item['CostPrice'] = result

            writer.writerow(item)

【问题讨论】:

不清楚你的问题是什么。也不清楚期望的结果应该是什么样子。 另外,你的 infile 头定义了 4 个字段,但下面只有 3 个。 好的,现在添加了预期的 outfile.csv。如您所见,应该填充 ChannelProfileID 和 CostPrice 项,但它们没有。 infile.csv 中的 CostPrice 列是空的并且没有值,但我会在那里添加值以作为更好的示例。 【参考方案1】:
import re
import csv
import collections
import glob

# Variables

total_record = []
headerCount = 0

for file in glob.glob("*.csv"):
    print(file)

    with open(file, 'r') as f:
        reader = csv.reader(f)
        list_record = list(reader)
        if headerCount == 0:
            headerCount = 1
            total_record.extend(list_record)
        else:
            list_record.pop(0)
            total_record.extend(list_record)

with open('combine.csv', 'w') as csvFile:
    writer = csv.writer(csvFile)
    writer.writerows(total_record)

【讨论】:

【参考方案2】:
import csv

product_result = 

with open('checkfile.csv', 'rb') as checkfile:
    checkreader = csv.DictReader(checkfile)

    for v in checkreader:
        product_result[v['ProductCode']] = (v[' Stock'], v[' CostPrice'])

with open('infile.csv', 'rb') as infile:
    with open('outfile.csv', 'wb') as outfile:
        reader = csv.DictReader(infile)
        writer = csv.DictWriter(outfile, reader.fieldnames)
        writer.writeheader()

        for item in reader:
            result = product_result.get(item['SKU'])
            if result:
               item['ChannelProfileID'], item['CostPrice'] = result
            else:
               item['ChannelProfileID'] = item['CostPrice'] = None

            writer.writerow(item)

【讨论】:

感谢您的回复 - 所以我将 infile 数据转换为元组。但是,如何将字典中“Stock”字段的值更新为 ChannelProfileID,然后在 outfile.csv 中将值“CostPrice”更新为 CostPrice? 继续,会不会是类似于 item['ChannelProfileID'] = result['Stock'] 基本上试图将数据从 Dictionary 写入特定的 CSV 字段 result 是一个元组,因此您只能使用整数作为其索引;我在这个例子中所做的是序列解包。 我很高兴听到这个消息。请记住将最佳答案标记为您问题的已接受答案。 :)【参考方案3】:

你可以让它更简单一点:

import csv

with open('checkfile.csv', 'rb') as checkfile:
    product_result = 
        record['ProductCode']: record for record in csv.DictReader(checkfile)

with open('infile.csv', 'rb') as infile:
    with open('outfile.csv', 'wb') as outfile:
        reader = csv.DictReader(infile)
        writer = csv.DictWriter(outfile, reader.fieldnames)
        writer.writeheader()
        for item in reader:
            record = product_result.get(item['SKU'], None)
            if record:
                item['ChannelProfileID'] = record[' Stock']  # ???
                item['CostPrice'] = record[' CostPrice']
            else:
                item['ChannelProfileID'] = None
                item['CostPrice'] = None
            writer.writerow(item)

我不确定我用??? 评论的那一行。

另外,如果您真的想生成损坏的 CSV,请随意省略 else 子句。

我用 StringIO 对象对其进行了测试。它产生了您指定的结果,但带有尾随逗号,在检查文件中没有匹配项。

我使用 Python 2.7 字典理解,因为你用 python-2.7 标记了你的问题。

【讨论】:

以上是关于使用 Python 字典在 Python 中合并 CSV 文件的主要内容,如果未能解决你的问题,请参考以下文章

在Python中合并字典的层次结构

python字典合并

python 在Python的中合并两个或以上字典

在python中合并字典值列表

在python中循环遍历数据框字典并将字典中的每个数据框与单个数据框合并

python多个字典“合并”成一个字典