我有相似数据集的不同来源(CSV),我想合并为单个数据并将其写入我的数据库。由于数据来自不同的来源,因此它们在CSV中使用不同的标头,因此我想将这些列具有逻辑含义。
到目前为止,我已经尝试过先读取所有标头,然后重新读取文件,以首先获取单个数据帧中的所有数据,然后进行是否将具有相同含义的列合并的操作。理想情况下,我想创建一个具有每列所有可能列名称的映射文件,然后使用该映射读取CSV。数据在文件之间未排序或排序。列数可能也有所不同,但是它们都有我感兴趣的列。
样本数据:
档案1:
id,名称,total_amount ...
1,“ test”,123 ..
文件2:
member_id,tot_amnt,名称
2,“ test2”,1234 ..
我希望它看起来像
id,名称,总计金额...
1,“ test”,123 ...
2,“ test2”,1234 ...
...
我想不出一种优雅的方法来做,这将是很好的指导或帮助。
谢谢
答案 0 :(得分:1)
使用skiprows
和header=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和地图-即
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)
答案 1 :(得分:1)
这就是我最终所做的,发现这是最干净的解决方案。谢谢大卫的帮助。
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)