合并具有不同列名但定义相同的多个CSV

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了合并具有不同列名但定义相同的多个CSV相关的知识,希望对你有一定的参考价值。

我有类似数据集的不同来源(CSV),我想合并到单个数据并将其写入我的数据库。由于数据来自不同的来源,他们在CSV中使用不同的标题,我想合并这些列的逻辑含义。

到目前为止,我已经尝试首先读取所有标题并重新读取文件以首先获取单个数据帧中的所有数据然后执行if else以将列合并在一起具有相同含义。理想情况下,我想创建一个包含每列所有可能列名的映射文件,然后使用该映射读取CSV。数据未在文件之间排序或排序。列数也可能不同,但它们都有我感兴趣的列。

样本数据: 档案1: id,name,total_amount ... 1,“测试”,123 ..

文件2: member_id,tot_amnt,name 2,“test2”,1234 ..

我希望这看起来像

id,name,total_amount ... 1,“测试”,123 ... 2,“test2”,1234 ...... ...

我想不出一个优雅的方法来做这个,很高兴得到一些指导或帮助。

谢谢

答案

使用skiprowsheader=None跳过标题,names指定您自己的列名列表,并使用concat合并为单个df。即

import pandas as pd

pd.concat([
    pd.read_csv('file1.csv',skiprows=1,header=None,names=['a','b','c']),
    pd.read_csv('file2.csv',skiprows=1,header=None,names=['a','b','c'])]
)

编辑:如果不同的文件仅按列顺序不同,您可以为names指定不同的列顺序,如果要选择列的子集,请使用usecols。但是您需要提前进行此映射,方法是探测文件或其他规则。

这需要以某种方式将文件映射到处理程序

file1.csv

id, name, total_amount
1, "test", 123

file2.csv

member_id, tot_amnt, ignore, name
2, 1234, -1, "test2"

以下选择常用的3列并重命名/重新排序。

import pandas as pd

pd.concat([
    pd.read_csv('file1.csv',skiprows=1,header=None,names=['id','name','value'],usecols=[0,1,2]),
    pd.read_csv('file2.csv',skiprows=1,header=None,names=['id','value','name'],usecols=[0,1,3])],
    sort=False
)

编辑2:

应用这个的一个好方法是使用lambda和map - 即

parsers = {
   "schema1": lambda f: pd.read_csv(f,skiprows=1,header=None,names=['id','name','value'],usecols=[0,1,2]),
   "schema2": lambda f: pd.read_csv(f,skiprows=1,header=None,names=['id','value','name'],usecols=[0,1,3]) 
}

map = {
    "file2.csv": "schema2",
    "file1.csv": "schema1"}

pd.concat([parsers[v](k) for k,v in map.items()], sort=False)
另一答案

这就是我最终做的事情,并且发现它是最干净的解决方案。谢谢大卫的帮助。

dict1= {'member_number': 'id', 'full name': 'name', …}
dict2= {'member_id': 'id', 'name': 'name', …}
parsers = {
   "schema1": lambda f, dict: pd.read_csv(f,index_col=False,usecols=list(dict.keys())),
   "schema2": lambda f, dict: pd.read_csv(f,index_col=False,usecols=list(dict.keys())) 
}      
map = {
    'schema1': (a_file.csv,dict1),
    'schema2': (b_file.csv,dict2)
}
total = []
for k,v in map.items():
    d = parsers[k](v[0], v[1])
    d.rename(columns=v[1], inplace=True)
    total.append(d)
final_df = pd.concat(total, sort=False)

以上是关于合并具有不同列名但定义相同的多个CSV的主要内容,如果未能解决你的问题,请参考以下文章

合并两个具有相同列名但在熊猫中列数不同的数据框

如何合并具有相同列名的多个数据框?

合并时如何使用列索引?

将来自不同文件夹的多个 csv 文件(相似名称)合并到一个 csv 中并逐行绑定它们 [关闭]

当两个表具有相同的 dist 和 sort 键,但列名不同时,Redshift 是不是执行合并连接?

PySpark 在创建包含现有列名的新列时读取多个文件