Выполните поиск в CSV и добавьте значение, если найдено правильное значение в другом CSV

У меня есть 2 CSV, которые выглядят так:

input.csv:

идентификатор артикул затраты_производство 12 h01 13 h02

search.csv:

артикул затраты_производство h01 14.95 h02 51,99

Я хочу использовать значение (sku) из search.csv для поиска совпадения в input.csv и, если совпадение будет найдено, оно должно добавить соответствующее значение из cost_production в столбец cost_production в input.csv и вывести его в новый файл.

Вот что у меня есть на данный момент:

    import csv

    ID, SKU, COSTS_PRODUCTION = 'id', 'sku', 'costs_production' # Field names referenced.

    # Read entire input file into a list.
    with open('input.csv', 'r', newline='') as inp:
        reader = csv.DictReader(inp)
        inputs = list(reader)

    # Update input rows that match data in search.csv file.
    with open('search.csv', 'r', newline='') as sea:
        sea_reader = csv.DictReader(sea)
        for row in sea_reader:
            SKU, COSTS_PRODUCTION = row[SKU], row[COSTS_PRODUCTION]
            for input_ in inputs:
                if input_[SKU] == SKU: # Match?
                    input_[COSTS_PRODUCTION] = row[COSTS_PRODUCTION]
                    break

    # Write updated input.csv data out into a file.
    with open('input_updated.csv', 'w', newline='') as outp:
        fieldnames = inputs[0].keys()
        writer = csv.DictWriter(outp, fieldnames)
        writer.writeheader()
        writer.writerows(inputs)

    print('done')

Я продолжаю получать KeyError: 'h01'.

Пожалуйста, рассмотрите возможность исправления отступов. Также включите полную ошибку трассировки.

ewokx 20.08.2024 12:00

Обратите внимание, что форматирование таблицы менее полезно, чем реальный файл CSV, который люди могут скопировать и вставить. Или, если предположить, что проблема заключается не столько в записи и чтении файлов, сколько в промежуточной обработке данных, полностью вырежьте файлы и покажите список словарей - приведите минимальный воспроизводимый пример.

jonrsharpe 20.08.2024 12:02
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
2
50
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Было бы проще, если бы вы рассмотрели возможность использования dataframe в pandas.

Например:

import pandas as pd

input_df = pd.read_csv('input.csv')
search_df = pd.read_csv('search.csv')

merged_df = pd.merge(input_df, search_df, on='sku', how='left')

# Fill the costs_production column with the corresponding values from search.csv
merged_df['costs_production'] = merged_df['costs_production_y'].fillna(merged_df['costs_production_x'])

merged_df = merged_df[['id', 'sku', 'costs_production']]
merged_df.to_csv('input_updated.csv', index=False)

Однако, если вы все еще рассматриваете возможность использования csv, проблема возникает из-за того, что переменные, содержащие ключи столбцов (SKU и COSTS_PRODUCTION), и переменные, содержащие фактические значения из строк CSV, имеют одинаковые имена. В частности, следующая строка вызывает проблему:

SKU, COSTS_PRODUCTION = row[SKU], row[COSTS_PRODUCTION]

Чтобы решить эту проблему, присвойте значения CSV переменным с уникальными именами, например:

# Update input rows that match data in search.csv file.
with open('search.csv', 'r', newline='') as sea:
    sea_reader = csv.DictReader(sea)
    for row in sea_reader:
        search_sku = row[SKU]
        search_costs_production = row[COSTS_PRODUCTION]
        for input_ in inputs:
            if input_[SKU] == search_sku:
                input_[COSTS_PRODUCTION] = search_costs_production
                break

С помощью JayPeerachai я немного поигрался, снова отфильтровал результаты и получил вот это как окончательное решение.

Возможно, это поможет некоторым из вас.

# Update input rows that match data in search.csv file. 
with open('search.csv', 'r', newline='') as sea: 
    sea_reader = csv.DictReader(sea) 
    for row in sea_reader: 
        # SKU, COSTS_PRODUCTION = row[SKU], row[COSTS_PRODUCTION] 
        # SKU = row[SKU] 
        for input_ in inputs: 
            # if input_[SKU] == SKU: # Match? 
            if input_['sku'] == row[SKU]: 
                try: 
                    input_[COSTS_PRODUCTION] = row[COSTS_PRODUCTION] 
                except KeyError: 
                    import ipdb ; ipdb.set_trace() 
                break 


filtered_inputs = [entry for entry in inputs if entry[COSTS_PRODUCTION] != ''] 

к вашему сведению: возможно, на DuckDB стоит посмотреть

import os
import tempfile
import duckdb

tmpDB=tempfile.NamedTemporaryFile().name

con = duckdb.connect(tmpDB)
con.sql("create table input as select * from read_csv( 'input.csv')")
con.sql("create table search as select * from read_csv( 'search.csv')")
con.sql("COPY (select input.id, input.sku, search.costs_production from input,search where input.sku = search.sku) TO 'input-updated.csv' (HEADER,DELIMITER '\t') ")

os.unlink(tmpDB)

#produces 
id  sku costs_production
12  h01 14.95
13  h02 51.99

Другие вопросы по теме