Как сравнить 2 разных файла csv и вывести различия

#python #python-3.x #csv #compare

#python #python-3.x #csv #Сравнить

Вопрос:

У меня есть 2 CSV-файла, которые являются New.csv и Old.csv, которые имеют около 1 тыс. строк и 10 столбцов, имеющих такую структуру:

введите описание изображения здесь

Если в новом файле .csv есть длинное имя (первый столбец), которого нет в старом файле.csv, я бы хотел, чтобы вся новая строка.csv была добавлена к changes.csv.

Я начал с этого, но это работает совсем не хорошо:

 def deltaFileMaker():
    with open('Old.csv', 'r', encoding='utf-8') as t1, open('New.csv', 'r', encoding='utf-8') as t2:
        fileone = t1.readlines()
        filetwo = t2.readlines()

    with open('changes.csv', 'w', encoding='utf-8') as outFile:
        for line in filetwo:
            if line not in fileone:
                outFile.write(line)



deltaFileMaker()

  

Я также пытался использовать csv-diff, но не смог найти способ преобразовать его вывод в файл csv

Обновить

 def deltaFileMaker():
    from csv_diff import load_csv, compare
    diff = compare(
        load_csv(open("old.csv",encoding="utf8"), key="longName"),
        load_csv(open("new.csv",encoding="utf8"), key="longName")
    )

        with open('changes.csv', 'w',encoding="utf8") as f:  
        w = csv.DictWriter(f, diff.keys())
        w.writeheader()
        w.writerow(diff)


deltaFileMaker()


  

Выполнение этого:
введите описание изображения здесь

Комментарии:

1. Каким был ваш код с использованием csv-diff?

2. Я просто сделал общий csv-diff new.csv old.csv --key=id , я не мог понять, как с ним что-то еще сделать

3. Вы использовали --key=id или --key=longName ?

4. Извините, да, я использовал longName

5. Если есть способ, которым я мог бы преобразовать csv-diff в файл csv, это было бы идеально

Ответ №1:

Вы смотрели csv-diff ? На их веб-сайте есть пример, который может подойти:

 from csv_diff import load_csv, compare
diff = compare(
    load_csv(open("one.csv"), key="id"),
    load_csv(open("two.csv"), key="id")
)
  

Это должно вернуть dict объект, который вы можете разобрать в файл CSV. Чтобы разобрать этот dict на строки, это пример. Примечание: добиться правильной записи изменений сложно, но это скорее проверка концепции — изменяйте по своему усмотрению

 from csv_diff import load_csv, compare
from csv import DictWriter

# Get all the row headers across all the changes
headers = set({'change type'})
for key, vals in diff.items():
    for val in vals: # Multiple of the same difference 'type'
        headers = headers.union(set(val.keys()))

# Write changes to file
with open('changes.csv', 'w', encoding='utf-8') as fh:
    w = DictWriter(fh, headers)
    w.writeheader()
    for key, changes in diff.items():
        for val in changes: # Add each instance of this type of change
            val.update({'change type': key}) # Add 'change type' data
            w.writerow(val)
  

Для файла one.csv :

 id,     name, age
 1,     Cleo,   4
 2, Pancakes,   2
  

и two.csv :

 id,   name, age
 1,   Cleo,   5
 3, Bailey,   1
4,  Elliot,  10
  

Запуск этого приводит к:

 change type,     name, id,               changes, age, key
      added,   Bailey,  3,                      ,   1,
      added,   Elliot,  4,                      ,  10,
    removed, Pancakes,  2,                      ,   2,
    changed,         ,   , "{'age': ['4', '5']}",    ,   1
  

Так что не очень подходит для всех изменений, но очень хорошо работает для добавленных / удаленных строк.

Комментарии:

1. Я пытался это сделать, но, должно быть, я делаю что-то не так. Пожалуйста, посмотрите на мое обновление. Если бы я мог разделить его на 3 отдельные таблицы внутри changes.csv с добавлением, изменением и удалением, это было бы потрясающе.

2. В чем проблема с тем, что у вас есть в вашем обновлении?

3. Только что добавлен скриншот, он помещает всю информацию в столбцы с именами добавлено, удалено и изменено.

4. Я обновлю свой пост, указав способ сделать то, что вы просите 🙂 @joe_sanders

5. Это моя ошибка, я никогда csv_diff раньше не использовал, я изменю свой пример, чтобы разрешить> 1 добавление / удаление @joe_sanders