【问题标题】:How to combine 2 csv files with common column value, but both files have different number of lines如何将 2 个具有公共列值的 csv 文件组合在一起,但两个文件的行数不同
【发布时间】:2012-08-21 20:08:49
【问题描述】:
file1.csv contains 2 columns: c11;c12
file2.csv contains 2 columns: c21;c22
Common column: c11, c21

例子:

f1.csv

a;text_a            
b;text_b            
f;text_f            
x;text_x

f2.csv

a;path_a
c;path_c
d;path_d
k;path_k
l;path_l
m:path_m

输出f1+f2:

a;text_a;path_a
b;text_b,''
c;'';path_c
d;'';path_d
f;text_f;''
k;'';path_k
l;'';path_l
m;'';path_m
x;text_x;''

如何用python实现?

【问题讨论】:

  • 如果你只需要这个,看看命令行join工具:linux.die.net/man/1/join
  • 感谢您的建议,但是非常欢迎提供一个示例如何在这种情况下使用 join 命令

标签: python csv


【解决方案1】:

使用 csv 模块很容易做到这一点:

import csv

with open('file1.csv') as f:
    r = csv.reader(f, delimiter=';')
    dict1 = {row[0]: row[1] for row in r}

with open('file2.csv') as f:
    r = csv.reader(f, delimiter=';')
    dict2 = {row[0]: row[1] for row in r}

keys = set(dict1.keys() + dict2.keys())
with open('output.csv', 'wb') as f:
    w = csv.writer(f, delimiter=';')
    w.writerows([[key, dict1.get(key, "''"), dict2.get(key, "''")]
                 for key in keys])

【讨论】:

  • 感谢您的回复。我还有一个问题。如果 file2.csv 有 3 列 i.s.o 2 列,则其他条件相同。这对代码有很大影响吗?
【解决方案2】:

对于基于一个或多个公共列合并多个文件(甚至 > 2),python 中最好和最有效的方法之一是使用“brewery”。您甚至可以指定需要考虑合并哪些字段以及需要保存哪些字段。

import brewery
from brewery
import ds
import sys

sources = [
    {"file": "grants_2008.csv",
     "fields": ["receiver", "amount", "date"]},
    {"file": "grants_2009.csv",
     "fields": ["id", "receiver", "amount", "contract_number", "date"]},
    {"file": "grants_2010.csv",
     "fields": ["receiver", "subject", "requested_amount", "amount", "date"]}
]

创建所有字段的列表并添加文件名以存储有关数据记录来源的信息。通过源定义并收集字段:

for source in sources:
    for field in source["fields"]:
        if field not in all_fields:

out = ds.CSVDataTarget("merged.csv")
out.fields = brewery.FieldList(all_fields)
out.initialize()

for source in sources:

    path = source["file"]

# Initialize data source: skip reading of headers
# use XLSDataSource for XLS files
# We ignore the fields in the header, because we have set-up fields
# previously. We need to skip the header row.

    src = ds.CSVDataSource(path,read_header=False,skip_rows=1)

    src.fields = ds.FieldList(source["fields"])

    src.initialize()


    for record in src.records():

   # Add file reference into ouput - to know where the row comes from
    record["file"] = path

        out.append(record)

# Close the source stream

    src.finalize()


cat merged.csv | brewery pipe pretty_printer

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-24
    • 2016-06-29
    • 1970-01-01
    • 2022-11-22
    • 1970-01-01
    • 2020-02-02
    • 2022-06-30
    • 1970-01-01
    相关资源
    最近更新 更多