Чтение из одного CSV-файла и запись в несколько разных CSV-файлов в зависимости от содержимого.

У меня есть большой файл csv, который я читаю. В зависимости от первых двух значений строки в столбце1 я хочу вывести содержимое в разные файлы csv.

Файл может выглядеть так:

Column1;Column2
01;BE
02;ED
12;FD
14;DS
03;ED
04;DF

Мой код выглядит следующим образом:

import csv
output_path=r'C:\myfolder\large_file.csv'

with open(os.path.join(os.path.dirname(output_path),"column1_01.csv"), "w", encoding = "utf-8", newline='') as \
out_01, open(os.path.join(os.path.dirname(output_path),"column1_02.csv"), "w", encoding = "utf-8", newline='') as \
out_02, open(os.path.join(os.path.dirname(output_path),"column1_03.csv"), "w", encoding = "utf-8", newline='') as \
out_03, open(os.path.join(os.path.dirname(output_path),"column1_04.csv"), "w", encoding = "utf-8", newline='') as \
out_04:
    
    cw01 = csv.writer(out_01, delimiter = ";", quoting=csv.QUOTE_MINIMAL)
    cw02 = csv.writer(out_02, delimiter = ";", quoting=csv.QUOTE_MINIMAL)
    cw03 = csv.writer(out_03, delimiter = ";", quoting=csv.QUOTE_MINIMAL)
    cw04 = csv.writer(out_04, delimiter = ";", quoting=csv.QUOTE_MINIMAL)

    with open(output_path, encoding = "utf-8") as in_f:
        cr = csv.reader(in_f, delimiter = ";")
        cw01.writerow(next(cr))
        cw02.writerow(next(cr))
        cw03.writerow(next(cr))
        cw04.writerow(next(cr))

        for line in cr:
            if (line[0][:2] = = "01"): cw01.writerow(line)  
            if (line[0][:2] = = "02"): cw02.writerow(line)  
            if (line[0][:2] = = "03"): cw03.writerow(line)  
            if (line[0][:2] = = "04"): cw04.writerow(line)  

Теперь моя проблема заключается в том, что когда я добавляю следующую строку, вывод для «05» я получаю остановку итерации ошибки (я проверил ее с помощью выборочных данных, и в ней не так много строк данных, поэтому я думаю, что это должно что-то делать с это). Кроме того, основная проблема заключается в том, что при проверке файлов я вижу, что это не сработало. Он не выводит записи в правильные файлы должным образом. Где моя ошибка?

Думаю проблема может быть во всем следующем(кр). Что я хочу сделать, так это просто использовать заголовок из исходного большого CSV и иметь его для каждого CSV. Заголовок тот же. Мне нужны все файлы в конце с заголовком.

Мне нужно чистое решение csv. Никаких других пакетов.

Я хотел бы найти точную ошибку в моем коде. Почему это не работает и где ошибка? Я не хочу никаких дальнейших изменений, вводящих обработку исключений, таких как try, функции, такие как def или любые другие. Мне не нужно универсальное решение. Я хочу найти конкретную ошибку в моем коде.

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

Для заголовка используйте header = next(cr), чтобы избежать повторения cr

Remi Cuingnet 10.01.2023 16:16

Куда мне поместить заголовок = next(cr) ?

PSt 10.01.2023 16:20

Я бы посоветовал cr = csv.reader(in_f, delimiter = ";"); header = next(cr); cw01.writerow(header); ...; cw04.writerow(header);

Remi Cuingnet 10.01.2023 16:25

Пожалуйста, опубликуйте это как ответ, чтобы я мог принять его.

PSt 10.01.2023 16:31
12;FD - это будет записано в файл или пропущено?
wwii 10.01.2023 17:05

@wwii Это будет пропущено.

PSt 10.01.2023 17:26
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Веб-скрейпинг, как мы все знаем, это дисциплина, которая развивается с течением времени. Появляются все более сложные средства борьбы с ботами, а...
Библиотека для работы с мороженым
Библиотека для работы с мороженым
Лично я попрощался с операторами print() в python. Без шуток.
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Привет, люди RPA, это снова я и я несу подарки! В очередном моем приключении о том, как создавать ботов для облегчения рутины. Вот, думаю, стоит...
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
Учебник по веб-скрапингу
Учебник по веб-скрапингу
Привет, ребята... В этот раз мы поговорим о веб-скрейпинге. Целью этого обсуждения будет узнать и понять, что такое веб-скрейпинг, а также узнать, как...
Тонкая настройка GPT-3 с помощью Anaconda
Тонкая настройка GPT-3 с помощью Anaconda
Зарегистрируйте аккаунт Open ai, а затем получите ключ API ниже.
0
6
53
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Что происходит, когда вы это делаете? Я перетасовал ваш код, чтобы сделать его универсальным, так что вы можете указать любой список cols, и он создаст 1 выходной файл для каждого столбца и найдет столбец в словаре авторов csv.

import csv
output_path = r'C:\myfolder\large_file.csv'


def get_fhandle(col_name):
  return open(
    os.path.join(os.path.dirname(output_path), f"column1_{col_name}.csv"),
    "w", encoding = "utf-8", newline=''
  )

cols = ["01", "02", "03", "04", "05"]
files = {col: get_fhandle(col) for col in cols}
try:
  writers = {
    col: csv.writer(file, delimiter = ";", quoting=csv.QUOTE_MINIMAL)
    for col, file in files.items()
  }
  with open(output_path, encoding = "utf-8") as in_f:
    cr = csv.reader(in_f, delimiter = ";")
    header = next(cr)
    for writer in writers.values():
      writer.writerow(header)
    for line in cr:
      col = line[0][:2]
      if col not in writers:
        raise ValueError(
          f"'{col}' is not a known column. Should be: {cols.join(', ')}"
        )
      writers[col].writerow(line)
finally:
  for file in files.values():
    file.close()

Нет, извини, но это не то, чего я хочу. Я хотел бы найти точную ошибку в моем коде. Почему это не работает и где ошибка? Я не хочу никаких дальнейших изменений, вводящих обработку исключений, таких как try, функции, такие как def или любые другие. Мне не нужно универсальное решение. Я хочу найти конкретную ошибку в моем коде.

PSt 10.01.2023 16:18

Хорошо, удачи с этим! Затем устраните неполадки в коде с помощью отладчика или распечатки.

Robin De Schepper 10.01.2023 16:19

В том, как я обрабатываю заголовок со следующим, есть ошибка, но я не знаю, почему. Я должен добавить его в каждый CSV-файл, в который я пишу, но так он не работает, так как у меня слишком много следующего.

PSt 10.01.2023 16:20

Использование contextlib.ExitStack() позволяет существенно навести порядок, особенно если мы настроим небольшой словарь, чтобы сопоставить, какие ключи в нашей карте ввода с тем, в какой выходной файл мы хотим записать.

import contextlib
import csv

files_out = {
    "01": "column1_01.csv",
    "02": "column1_02.csv",
    "03": "column1_03.csv",
    "04": "column1_04.csv",
}

with contextlib.ExitStack() as stack:
    ## ---------------------
    ## Set up a bunch of csv writers
    ## ---------------------
    writers = {
        key: csv.writer(stack.enter_context(open(value, "w", newline = "")))
        for key, value
        in files_out.items()
    }
    ## ---------------------

    file_in = stack.enter_context(open("small.csv"))
    rows = csv.reader(file_in, delimiter = ";")

    ## ---------------------
    ## write a header to each output file
    ## ---------------------
    headers = next(rows)
    for writer in writers.values():
        writer.writerow(headers)
    ## ---------------------

    ## ---------------------
    ## write rows to the appropriate file
    ## ---------------------
    for row in rows:
        key = row[0]
        if not key in writers:
            print(f"no file defined for key {key}")
            continue
        writers[key].writerow(row)
    ## ---------------------

Чтобы ответить на ваш конкретный вопрос о том, почему ваш код в настоящее время не работает, давайте посмотрим на:

with open(output_path, encoding = "utf-8") as in_f:
    cr = csv.reader(in_f, delimiter = ";")
    cw01.writerow(next(cr))
    cw02.writerow(next(cr))
    cw03.writerow(next(cr))
    cw04.writerow(next(cr))

    for line in cr:
        if (line[0][:2] = = "01"): cw01.writerow(line)  
        if (line[0][:2] = = "02"): cw02.writerow(line)  
        if (line[0][:2] = = "03"): cw03.writerow(line)  
        if (line[0][:2] = = "04"): cw04.writerow(line)  

Здесь:

cw01.writerow(next(cr))

По существу записывает первую строку (заголовок) вашего входного файла в первый выходной файл. Затем мы повторяем это, записывая последовательные строки ввода в выходные данные.

После записи первых 4 строк ввода в одну строку в каждом из четырех выходов мы затем читаем оставшиеся строки во входном файле (последние две в примере) и записываем их в файлы 3 и 4 по мере необходимости.

Итак, вашим конкретным решением было бы использовать next() один раз, чтобы получить заголовок из вашего входного файла, а затем записать его в каждый из ваших выходных файлов:

with open(output_path, encoding = "utf-8") as in_f:
    cr = csv.reader(in_f, delimiter = ";")
    headers = next(cr)

    cw01.writerow(headers)
    cw02.writerow(headers)
    cw03.writerow(headers)
    cw04.writerow(headers)

    for line in cr:
        if (line[0][:2] = = "01"): cw01.writerow(line)  
        if (line[0][:2] = = "02"): cw02.writerow(line)  
        if (line[0][:2] = = "03"): cw03.writerow(line)  
        if (line[0][:2] = = "04"): cw04.writerow(line)  
Ответ принят как подходящий

Встроенная функция Python next Получить следующий элемент из итератора, вызвав его __next__() метод. Таким образом, итератор перемещается вперед к следующему элементу. Следовательно, вы вызываете next много раз, чтобы получить заголовок.

[...]
    with open(output_path, 'r', encoding = "utf-8") as in_f:
        cr = csv.reader(in_f, delimiter = ";")
        header = next(cr)
        cw01.writerow(header)
        cw02.writerow(header)
        cw03.writerow(header)
        cw04.writerow(header)

        for line in cr:
[...]

Надеюсь, это поможет.

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