Вопрос:
У меня есть файл CSV, как показано ниже. Это огромный файл с тысячами записей.
input.csv
No;Val;Rec;CSR 0;10;1;1200 0;100;2;1300 0;100;3;1300 0;100;4;1400 0;10;5;1200 0;11;6;1200
Я хочу создать файл output.csv, добавив новый столбец “PSR” после 1-го столбца “Нет”. Значение этого столбца зависит от значения столбца “PSR”. Для 1-й строки значение “PSR” равно нулю. Начиная с следующей записи, это зависит от значения “CSR” в предыдущей строке. Если текущее и предыдущее значение CSR записи одинаково, то “PSR” должно быть равно нулю. Если нет, значение PSR должно иметь предыдущее значение CSR. Например, значение CSR во второй строке равно 1300, что отличается от значения в первой записи (это 1200). Поэтому значение PSR для 2-й строки должно быть 1200. Где во 2-й и 3-й строке значение CSR одинаково. Поэтому значение PSR для третьей строки равно нулю. Таким образом, новое значение PSR зависит от значения CSR в текущем и предыдущем поле.
output.csv
No;PCR;Val;Rec;CSR 0;0;10;1;1200 0;1200;100;2;1300 0;0;100;3;1300 0;1300;100;4;1400 0;1400;10;5;1200 0;0;11;6;1200
Мой подход:
- Используйте csv.reader и перебирайте объекты в списке. Скопируйте 5-й столбец во второй столбец в списке. Сдвиньте его на одну строку вниз.
- Затем проверьте значения во втором и пятом столбцах (PCR и CSR), если оба значения одинаковы. Замените значение ПЦР на ноль.
У меня проблема с кодированием 1-го шага. Я могу дублировать столбец, но не могу его переместить. Также второй шаг довольно прост.
Кроме того, я не уверен, правильный ли этот подход. Любые указатели/рекомендации были бы действительно полезными.
Примечание. Я не могу установить Pandas на CentOS. Поэтому помощь без этого модуля была бы лучше.
Мой код:
with open(‘input.csv’, ‘r’) as input, open(‘output.csv’, ‘w’) as output: reader = csv.reader(input, delimiter = ‘;’) writer = csv.writer(output, delimiter = ‘;’) mylist = [] header = next(reader) mylist.append(header) for rec in reader: mylist.append(rec) rec.insert(1, rec[3]) mylist.append(rec) writer.writerows(mylist) Лучший ответ:
Если ваши открытые решения, отличные от python, тогда awk может быть хорошим вариантом:
awk ‘NR==1{$2=»PSR;»$2}NR>1{$2=($4==a?0″;»$2:+a»;»$2);a=$4}1′ FS=’;’ OFS=’;’ file No;PSR;Val;Rec;CSR 0;0;10;1;1200 0;1200;100;2;1300 0;0;100;3;1300 0;1300;100;4;1400 0;1400;10;5;1200 0;0;11;6;1200
Awk распространяется практически во всех дистрибутивах Linux и предназначен именно для такого рода задач. Он просочится через ваш файл. Добавьте перенаправление в конец > output.csv чтобы сохранить вывод в файле.
Простой подход python с использованием той же логики:
#!/usr/bin/env python last = «0» with open(‘input.csv’) as csv: print next(csv).strip().replace(‘;’, ‘;PSR;’, 1) for line in csv: field = line.strip().split(‘;’) if field[3] == last: field.insert(1, «0») else: field.insert(1, last) last = field[4] print ‘;’.join(field)
Производит тот же вывод:
$ python parse.py No;PSR;Val;Rec;CSR 0;0;10;1;1200 0;1200;100;2;1300 0;0;100;3;1300 0;1300;100;4;1400 0;1400;10;5;1200 0;0;11;6;1200
Снова просто перенаправьте вывод, чтобы сохранить его:
$ python parse.py > output.csv Ответ №1with open(‘input.csv’, ‘r’) as input, open(‘output.csv’, ‘w’) as output: reader = csv.reader(input, delimiter = ‘;’) writer = csv.writer(output, delimiter = ‘;’) header = next(reader) header.insert(1, ‘PCR’) writer.writerow(header) prevRow = next(reader) prevRow.insert(1, ‘0’) writer.writerow(prevRow) for row in reader: if prevRow[-1] == row[-1]: val = ‘0’ else: val = prevRow[-1] row.insert(1,val) prevRow = row writer.writerow(row) Ответ №2
Просто введите код, как вы это объяснили. Сохраните предыдущую CSR и обратитесь к ней в следующем цикле; просто обязательно обновите его.
import csv with open(‘input.csv’, ‘r’) as input, open(‘output.csv’, ‘w’) as output: reader = csv.reader(input, delimiter = ‘;’) writer = csv.writer(output, delimiter = ‘;’) mylist = [] header = next(reader) mylist.append(header) mylist.insert(1,’PCR’) prev_csr = 0 for rec in reader: rec.insert(1,prev_csr) mylist.append(rec) prev_csr = rec[4] writer.writerows(mylist) Ответ №3
Или, еще проще, используя возможности DictReader и DictWriter csv:
input_header = [‘No’,’Val’,’Rec’,’CSR’] output_header = [‘No’,’PCR’,’Val’,’Rec’,’CSR’] with open(‘input.csv’, ‘rb’) as in_file, open(‘output.csv’, ‘wb’) as out_file: in_reader, out_writer = DictReader(in_file, input_header, delemeter =’;’), DictWriter(out_file, output_header, delemeter =’;’) in_reader.next() # skip the header out_writer.writeheader() # place the output header last_csr = None for row in in_reader(): current_csr = row[‘CSR’] row[‘PCR’] = last_csr if current_csr != last_csr else 0 last_csr = current_csr out_writer.writerow(row)