Найти - Пользователи
Полная версия: CSV-файл - определение и изменение кодировки
Начало » Python для новичков » CSV-файл - определение и изменение кодировки
1 2 3 4
coffe4wolf
ZerG
ZerG
А откудова идет импорт? может вам проще на питоне сразу коненкт в базу данных написать и делать выборку?
С софтины APACS 3000, которая по списку сотрудников делают выгрузку времени посещения за определённый период. Думаю писать такой коннект с выборкой будет слишком громоздко. Проще выгружать тиблицу csv'шкой и резать скриптом. Вообще по идее можно справиться и средствами экселя, но думаю если будет готовый скрипт для этого, будет всё же удобнее. К тому же учу язык по ходу
py.user.next
Чем мне кодировку точно определить? Как писал, несколько разных программ дают разные ответы на этот вопрос D:
После того как определю кодироку, декодирую полученные строки, совершаю необходимые операции, потом кодирую обратно(кстати во что лучше кодировать? Вычитал в одной статье, что предпочтительнее utf-8 из-за распространённости)? Перевод в юникод не должен участвовать в этой цепочке?
ZerG
как раз таки если доступ к базе есть то легче делать запрос из нее чем заходить в прогу - делать експорт - сохранять в файл читать файл парсить - сохранять результат
coffe4wolf
ZerG
Придётся писать выборку по определённому промежутку времени и по именам/отделам/должностям и т.д., а к этому всему ещё и интерфейс D:
py.user.next
coffe4wolf
Чем мне кодировку точно определить? Как писал, несколько разных программ дают разные ответы на этот вопрос
В идеале, сам файл должен храниться в utf-8. Кодировку ты никак не определишь, её надо знать (иметь записанной для каждого источника данных). То есть у тебя должен быть отдельный конвертер, который переводит файл из одной кодировки в другую. Этот конвертер должен получать на вход три параметра: кодировка из, кодировка в, и путь к файлу. А на выходе он делает новый файл в правильной кодировке. И вот когда у тебя есть правильный файл, он подаётся уже скрипту анализа полей. Когда ты их обработал и сохранил, конвертер обратно его преобразует (если надо), чтобы в той программе, откуда он пришёл, он отображался правильно.

То есть для каждого источника у тебя конвертер один и тот же, различаются только настройки конвертера.

coffe4wolf
Перевод в юникод не должен участвовать в этой цепочке?
Ты когда через codecs.open() открываешь с указанием кодировки, он уже переводит в юникод. utf-8 покрывает весь юникод, в отличие от других кодировок типа cp1251 и подобных.

Вот пример
>>> import codecs
>>> 
>>> f = codecs.open('/etc/passwd', encoding='utf-8')
>>> s = f.readline()
>>> s
u'root:x:0:0:root:/root:/bin/bash\n'
>>> f.close()
>>> 
>>> import csv
>>> 
>>> reader = csv.reader([s], delimiter=':')
>>> list(reader)
[['root', 'x', '0', '0', 'root', '/root', '/bin/bash']]
>>>
Там буква u перед строкой как раз и означает, что это строка юникодовых символов.
doza_and
coffe4wolf
Проблема в том, что есть строки вида
Владимиров М.Ю.;;;
;17.04.2016 7:47:52;17.04.2016 20:08:53;
Много писанины а проблема не обсуждается. Насколько я понимаю проблема в том что переводы строки попадаются “посреди строки”. Это не csv файл и читать его csv ридером не имеет смысла. Опирайтесь на то что формат строгий, можно опереться на количество полей.
import codecs
import re
with codecs.open("testcsv.csv","r",encoding="cp1251") as f:
    data=f.read()
ds = re.split(r"[;\r\n]",data)
for i in range(15,len(ds)-1,10):
    if ds[i+1]:
        print(ds[i])

coffe4wolf
doza_and
Кстати всё же не понимаю - почему не csv файл? Если поставлю разделители запятые он им типа станет? о.О
doza_and
Насколько я понимаю проблема в том что переводы строки попадаются “посреди строки”.
Не, судя по “сырому” выводу переводы строки в конце строки. Проблема удалить определённые строки, не удалив при этом лишние. Например выбрать строки так, чтобы удалить всё строки вида
Иванов И.И.;;;
;;;
Но оставить пары строк вида
Иванов И.И.;;;
;16.04.2016 11:03:53;16.04.2016 18:35:25;
doza_and
coffe4wolf
Проблема удалить определённые строки,
Вас вывод моего кода устраивает? Там все решено. В чем еще проблемы?
coffe4wolf
почему не csv файл?
https://ru.wikipedia.org/wiki/CSV “текстовый формат, предназначенный для представления табличных данных” “Каждая строка файла — это одна строка таблицы. Строки разделяются парой символов CR LF (0x0D 0x0A)”
У вас строки не содержат элементы одной таблицы, если следовать вашей интерпретации. Для CSV это недопустимо.

Я подозреваю что вы неправильно интерпретируете ваш файл.

Иванов И.И.;;;
;16.04.2016 11:03:53;16.04.2016 18:35:25;

Скорее всего это Иванов пришедший незнамо когда и незнамо кто пришедший в 16.04.2016 11:03:53. Т.е две разные не связанные записи. Тогда его можно читать CSV ридером.
py.user.next
coffe4wolf
Кстати всё же не понимаю - почему не csv файл?
Это не csv-файл только по одной причине - у него разделитель не запятая. Это dsv-файл, где разделитель - точка с запятой.

doza_and
Насколько я понимаю проблема в том что переводы строки попадаются “посреди строки”.
У него там просто записи с пустыми полями, потому что это бралось из такой таблицы - с пустыми полями.

А переводы строки могут быть и внутри записи csv-файла (но тогда они должны быть проэкранированы кавычками), потому что csv может представлять любой текст, в том числе и многострочный.
https://tools.ietf.org/html/rfc4180
   6.  Fields containing line breaks (CRLF), double quotes, and commas
should be enclosed in double-quotes. For example:

"aaa","b CRLF
bb","ccc" CRLF
zzz,yyy,xxx
coffe4wolf
doza_and
Вывод хороший, но он отрезал все строки со временем Но думаю попытаюсь смогу из кода сделать то, что нужно
doza_and
Я подозреваю что вы неправильно интерпретируете ваш файл.
Да нет, всё верно. Опишу всё более полно, дабы прояснить.
Программа даёт мне отчёт в фиксированном виде
Самая первая строка файла - заголовок:
ФИО;Первый приход;Последний уход;
Потом идут строки с фамилиями и временем.
Если, например, я запросил данные по Арбузову А.А. за определённый период, то в таблице он появится в таком виде
Арбузов А.А.;;;
;;;
Если запросил данные по Баранову Б.Б. и у него было посещение, в первый день временного отрезка, по которому я запросил отчёт, то вывод будет такой
Баранов Б.Б.;16.04.2016 14:09:36;16.04.2016 15:48:11;
;;;
А если же у Баранова были посещения не только в первый день, но и во второй, то вывод будет таким
Баранов Б.Б.;16.04.2016 8:37:16;16.04.2016 20:12:24;
;17.04.2016 8:22:54;17.04.2016 22:06:33;
Если же Баранов не был в первый день, но был во второй, то вид такой
Баранов Б.Б.;;;
;17.04.2016 7:47:52;17.04.2016 20:08:53;
То есть если на первой строке есть Баранов, но нет времени, а на сразу следующей строке есть время, но нет Баранова - то это время однозначно относится к Баранову, а не к кому либо ещё. Так отчёт генерируется программой.
Каждая строка здесь соответствует одной строке в таблице.
Соответственно если я включаю в отчёт несколько человек, то все они попадают в одну большую таблицу.
В экселе это выглядит примерно так

Моя задача удалить из таблицы всяких Арбузовых, а всяких Барановых во всех трёх вариантах оставить.

py.user.next
py.user.next
Это не csv-файл только по одной причине - у него разделитель не запятая. Это dsv-файл, где разделитель - точка с запятой.
У меня есть возможность формировать эти таблицы с разделителем запятой. Лучше формировать отчёт с этим разделителем, чтобы можно было работать с csv-модулем? Хотя в принципе же, при инициализации ридера или райтера можно задать любой желаемый разделитель и работать с файлом как с обычным csv. Или я неправильно понимаю?

ZerG
Так а нафига вы вобще с CSV что-то делаете если есть прекрасная возможность работать с файлами екселя в питоне? ?????


повторю еще раз - на всякий случай!
Гораздо проще цепляться к базе данных и выгребать то что вам нужно - формировать ето в что угодно и так далее ! Чем настраивать импоры кодировки И так далее и тп
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB