Объединить несколько CSV с другим именем столбца, но с одинаковым определением - PullRequest
1 голос
/ 16 апреля 2019

У меня есть разные источники (CSV) схожего набора данных, которые я хочу объединить в отдельные данные и записать их в мою БД.Поскольку данные поступают из разных источников, они используют разные заголовки в своем CSV, я хочу объединить эти столбцы с логическим значением.

До сих пор я пытался сначала прочитать все заголовки и перечитать файлы, чтобы сначала получитьвсе данные в одном фрейме данных, а затем делать, если еще, чтобы объединить столбцы с одинаковым значением.В идеале я хотел бы создать файл сопоставления со всеми возможными именами столбцов для каждого столбца, а затем прочитать CSV, используя это сопоставление.Данные не упорядочены или не отсортированы между файлами.Количество столбцов тоже может быть разным, но все они имеют интересующие меня столбцы.

Пример данных:
Файл 1:
id, name, total_amount ...
1, "test ", 123 ..

Файл 2:
member_id, tot_amnt, name
2," test2 ", 1234 ..

я хочу, чтобы это выглядело

id, name, total_amount ...
1, "test", 123 ...
2, "test2", 1234 ...
...

Iне могу придумать элегантный способ сделать это, было бы замечательно получить направление или помочь с этим.

Спасибо

Ответы [ 2 ]

1 голос
/ 16 апреля 2019

Это то, что я в итоге сделал и нашел самое чистое решение. Спасибо, Дэвид, за помощь.

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)
1 голос
/ 16 апреля 2019

Используйте 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:

И хороший способ применить это - использовать лямбду и карты - т.е.

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...