Как перезаписать определенную ячейку в CSV файле?

Рейтинг: 2Ответов: 2Опубликовано: 18.04.2015

Как перезаписать определенную ячейку в столбце в CSV файле?

Например, надо 5-й столбец и 6-я строка. В документации к модулю CSV не нашел такого примера.

Ответы

▲ 2
def update_csv_cell(address, new_value):

    filepath = '/home/idle/so/some.csv'
    dialect_params = dict(delimiter=';')
    col_num, row_num = address

    with open(filepath, 'r+b') as csvfile:
        reader = csv.reader(csvfile, **dialect_params)
        lines = []

        for current_line in reader:
            if reader.line_num == row_num:
                current_line[col_num-1] = new_value
            lines.append(current_line)

        csvfile.seek(0)
        csv.writer(csvfile, **dialect_params).writerows(lines)
        csvfile.truncate()


update_csv_cell(address=(5, 6), new_value='replaced')

Выше приведён базовый код, без обработки ошибок.

Плохих новостей больше, чем хороших.

Хорошая: модуль csv позволяет работать с обычными объектами-файлами, а значит вам доступны все методы таких объектов (см. seek, tell и т.п.)

Плохая 1: модуль csv считывает файл целиком, поэтому в ходе итерирования по строкам файла метод tell будет всегда будет возвращать позицию конца файла, поэтому иного простого решения, кроме как считать все данные, изменить их и пересохранить на горизонте нет.

Плохая 2: Подход с обращением к данным файла по позиции в документе ненадёжен, потому как, если со столбцами всё может быть относительно стабильно, то с рядом очень возможно и не угадать, испортив при этом данные.

▲ 2

При работе с CSV (да и вообще при работе с данными) очень удобно и почти всегда более производительно пользоваться Pandas:

Пример:

читаем / парсим CSV в Pandas Data Frame при помощи read_csv() метода:

import pandas as pd

In [115]: df = pd.read_csv('c:/temp/example.csv', sep=',')

In [116]: df
Out[116]:
    A   B   C   D   E
0  54   9  74  73  59
1  34  20  66  81  14
2  89  33  87  98  41
3  74  78  19   4  25
4  30  12   7  52  29
5  33  45  39  73  81
6  49  28  48  69  99

меняем 6 строку и 5 столбец (внимание: в Pandas как и в Python нумерация начинается с нуля):

In [119]: df.ix[6-1, 5-1] += 1000

In [120]: df
Out[120]:
    A   B   C   D     E
0  54   9  74  73    59
1  34  20  66  81    14
2  89  33  87  98    41
3  74  78  19   4    25
4  30  12   7  52    29
5  33  45  39  73  1081
6  49  28  48  69    99

записываем обратно в CSV:

df.to_csv('c:/temp/example.csv', index=False)

Результат:

A,B,C,D,E
54,9,74,73,59
34,20,66,81,14
89,33,87,98,41
74,78,19,4,25
30,12,7,52,29
33,45,39,73,1081
49,28,48,69,99

Как легко и быстро сгенерировать тестовые данные (именно так был создан тестовый CSV):

import numpy as np

df = pd.DataFrame(np.random.randint(0,100,size=(7, 5)), columns=list('ABCDE'))
df.to_csv('c:/temp/example.csv', index=False)

или одной строкой:

pd.DataFrame(np.random.randint(0,100,size=(7, 5)), columns=list('ABCDE')).to_csv('c:/temp/example.csv', index=False)