Python - добавление начальных нулей к цифрам даты в файле CSV
Использование Python 3.3 на Win8. Я бы посчитал себя новичком в написании сценариев. Я пытаюсь работать с датами в электронной таблице Excel без начальных нулей. В конце года всегда 2 цифры, месяц идет первым, а затем день находится посередине. Я могу извлечь столбец Excel, чтобы поместить его отдельно в файл. Ниже приведены некоторые примеры того, с чем я могу столкнуться с тысячами строк, чтобы пройти и зафиксировать даты в узнаваемых форматах:
1188 (MDYY) 11188 (дата проблемы) 12188 (Date проблемы) 13188 (MDYY) 21188 (MDDYY) 111188 (MMDDYY)
Я думаю, у меня есть 2 части к моему вопросу: (1) С каким типом файла легче всего работать при модификации с использованием Python (например, XLSX, XLS, CSV, TXT и т. Д.) (2) Любые советы по кодированию приведенной ниже логики с Python... может быть, функции для использования?
Ниже приведена моя логика, которую я хотел бы применить, потому что я знаю, что нет способа определить, действительно ли даты имеют только 5 цифр и начинаются с "11" или "12", поэтому я хочу вместо этого поместить ОШИБКУ, чтобы мы могли вернуться назад чтобы исправить это вручную. По идее чем меньше ручного труда, тем лучше.
- Всегда 2 цифры для года в конце, поэтому нужно сразу разобрать с оставшимися цифрами слева
- ЕСЛИ цифры года от "00" до "30", ТО присоедините начальную "20" к четырехзначному году
- Еще прикрепите ведущий "19", чтобы сформировать 4-значный год
- Подсчитать количество цифр, оставшихся после удаления цифр года
- ЕСЛИ общее количество оставленных цифр = 2, ТО разбор первой и второй цифр И добавление начального нуля к обеим цифрам
- ElseIF всего осталось цифр = 3 ТО
- Если первые два числа равны "11" или "12", выведите окончательные результаты как "ОШИБКА"
- Иначе, если первые два числа равны "10", ТОГДА разбираются как есть И добавляют начальный ноль к третьей цифре
- Еще раз разбираем первую цифру И добавляем начальный ноль, ТО разбираем оставшиеся 2 цифры как есть
- Еще осталось всего цифр = 4, ТО ничего не делать
- Убедитесь, что дата составлена в новом формате для окончательного результата
Большое спасибо за любую помощь и удар, чтобы начать самостоятельно!
МОЕ ПУТЕШЕСТВИЕ
Изначально мне нужна была помощь в получении моей логики в Python, затем я боролся со следующим, но в итоге добился успеха, потратив время на исследования и полезных людей в stackru: чтение / запись / добавление CSV-файлов, заполнение первых нулей, заполнение первых цифр за год, синтаксис, неверные типы данных и т.д... СПАСИБО ВСЕМ, ЧТО ПОМОГЛО!!!
ЗАКОНЧЕННЫЙ КОД НИЖЕ!!!!!!!
import csv
# Change to location of CSV file
with open('c:\\Users\\Weez\\Desktop\\csv_test.csv', newline='') as csvfile:
csvreader = csv.reader(csvfile)
for line in csvreader:
baddate = line[0]
year = int(baddate) % 100
md = int(baddate) // 100
# Check year values
if year < 10:
year = str(200)+str(year)
elif year <= 50:
year = str(20)+str(year)
else:
year = str(19)+str(year)
# Check month and day values
if md < 100:
month = md // 10
month = str(month).zfill(2)
day = md % 10
day = str(day).zfill(2)
elif md >= 1000:
pass
elif md <= 109:
month = md // 10
day = md % 10
day = str(day).zfill(2)
elif md == 110:
month = md // 100
month = str(month).zfill(2)
day = md % 100
elif md == 120:
month = md // 100
month = str(month).zfill(2)
day = md % 100
elif md <= 129:
month = str("XX")
day = str("XX")
else:
month = md // 100
month = str(month).zfill(2)
day = md % 100
dateresult = str(month)+str(day)+str(year)
print(dateresult)
# modes 'a' = append, 'w' = write, 'r' = read and other modes
with open('c:\\Users\\Weez\\Desktop\\csv_test_output.csv', 'a') as csvoutput:
csvoutput.write(dateresult)
csvoutput.write('\n')
print('\n')
print('\n')
str(input("Process complete! Press Enter to finish!"))
3 ответа
Поскольку год всегда состоит из двух цифр, вы можете сразу устранить эту часть проблемы.
year = date % 100
md = date // 100
Теперь вы можете исключить двухзначные и четырехзначные регистры:
if md < 100:
month = md / 10
day = md % 10
elif md >= 1000:
month = md / 100
day = md % 100
Теперь вы можете определить потенциальные проблемные области и устранить неоднозначность.
elif md <= 109:
month = 10
day = md % 10
elif md == 110:
month = 1
day = 10
elif md <= 129:
month = None # ambiguous
day = None
else:
month = md / 100
day = md % 100
Вам нужно будет выполнить дополнительную проверку, чтобы убедиться, что месяц и день не выходят за рамки.
Для № 1 вы можете использовать csv
хотя у меня нет опыта работы с другими модулями:(.
Для #2, вы можете использовать встроенный модуль, datetime
>>> from datetime import datetime
>>> date_unpadded_month = '1188'
>>> date_padded_month = '01188'
>>> date_2_digit_month = '11188'
>>> date_format = '%m%d%y'
>>> parsed = datetime.strptime(date_unpadded_month, date_format)
>>> parsed
>>> datetime.datetime(1988, 1, 1, 0, 0)
>>> parsed = datetime.strptime(date_padded_month, date_format)
>>> parsed
>>> datetime.datetime(1988, 1, 1, 0, 0)
>>> parsed = datetime.strptime(date_2_digit_month, date_format)
>>> parsed
>>> datetime.datetime(1988, 11, 1, 0, 0)
>>> parsed.month
>>> 11
Если даты в электронной таблице в порядке, вы можете задним числом вернуться и исправить ранее неоднозначные даты с высоким уровнем успеха. Например, если у вас есть
123087, 11188, 22288
Первая и последняя даты не однозначны (Dec-30-'87
& Feb-22-'88
), а средняя дата либо Jan-11-'88
или же Nov-1-'88
, но может быть решена, если вы знаете, что три даты в порядке.
Изменить: вот код для достижения этого:
from datetime import datetime
data = '123087', '1188', '11188', '22288', '11188' # some 4, 5 and 6 digit dates
fmt = '%m%d%y'
results = []
# parse possible dates from data
for date_str in data:
alt_date_str = ('0' + date_str)[-6:]
dates = (datetime.strptime(d, fmt) for d in (date_str, alt_date_str))
results.append(set(dates)) # make sure dates are unique
# iterate through results, removing anything older than the previous entries
oldest = datetime.min
for i in xrange(len(results)):
results[i] = [d for d in results[i] if d > oldest]
oldest = min(results[i])
# iterate backwards, removing anything newer than the previous entries
newest = datetime.max
for i in reversed(xrange(len(results))):
results[i] = [d for d in results[i] if d < newest]
newest = max(results[i])
# show dates, error if still ambiguous
for dates in results:
if len(dates) > 1:
print 'ERROR:', dates
else:
print dates[0]