Как в python выбрать дату из большого числа в каждой строке столбца из excel и записать результат по условию в соседний столбец excel?
Есть столбец в excel с номерами ИИН (в Казахстане), где первые 6 цифр - это зашифрованная дата рождения, а остальные цифры не важны совсем. Например, 760729000345 - это:1976-07-29 (1976 год июль (07) и 29 (дата)) или 961213789432 - это 1996-12-13. Остальные цифры не важны. Нужно из всего столбца (там больше 10 тыс записей) в питоне найти дни рождения и записать их в excel напротив ИИН в соседний столбец.
Плюс есть часть ИИН, которые юр.лица и там может быть 13 месяц или 65 число. Т.е. в этих строчках нужно поставить "ТОО" и не высчитывать дату.
Я не понимаю 2 вещи: как к каждой строчке в эксель средствами питона написать дату рождения и как это потом записать в сам эксель.
У меня получается: либо в эксель только последнее значение записывается, либо сначала одна дата рождения на все ИИН, потом вторая дата на все ИИН итд. Не понимаю, что делаю не так. Уже 3 неделю вожусь. Очень прошу помочь. Я совсем начинающая в питоне. Прошу сильно не ругать и помочь, пожалуйста, по возможности. Никак не получается.
Вот мой код:
import pandas as pd # подгружаем библиотеку, чтобы работать с файлом
df = pd.read_excel(r"C:\Users\Oct-21\1.xlsx") # загружаем исходный файл
from datetime import date
import time
counter = 0
data_df = df['ИИН'].astype(pd.StringDtype())
for row in data_df:
year = int(row[0:2])
if 22 <= year <= 99:
year += 1900
else:
year += 2000
day = int(row[4:6])
month = int(row[2:4])
try:
data=datetime.date(year,month,day)
print(data)
except:
print("ТОО")
counter +=1
print(counter)
Так код в питоне работает и все считает, но я не понимаю, как его в excel отправить, чтобы он был отдельным столбцом и в каждой строчке свое значение.
Если делаю вот так:
from datetime import date
import time
counter = 0
data_df = df['ИИН'].astype(pd.StringDtype())
c = data_df
for row in data_df:
year = int(row[0:2])
if 22 <= year <= 99:
year += 1900
else:
year += 2000
day = int(row[4:6])
month = int(row[2:4])
try:
a = datetime.date(year,month,day)
b = pd.Series(a)
df['Дата'] = b
print(df['Дата'])
except:
print("ТОО")
counter +=1
то каждый раз перезаписывается именно первая строка.
Примеры ИИН (столбец из excel из которого берутся данные):
780913204527
Спасибо всем за помощь от всей души! Всем любви и добра!
Ответы (1 шт):
Можно так.
Создадим функцию
def convert_date(x):
try:
val = pd.to_datetime(str(x)[:6], yearfirst=True, format='%y%m%d').date()
if val >= pd.Timestamp.today().date():
return (val - pd.DateOffset(years=100)).date()
else:
return val
except:
return 'TOO'
iin = [740603400216,631004302309,760127300474,740418400032,680919301301,730302301686,600727300553,710404301805,661210301930, 691025401917,930513351265,750618300709,731010301512,780315300370,
650704300130, 901006351464........]
df = pd.DataFrame({'date_of': iin})
df['new_date'] = df['date_of'].apply(lambda x: convert_date(x))
>>> df
date_of new_date
0 740603400216 1974-06-03
1 631004302309 1963-10-04
2 760127300474 1976-01-27
3 740418400032 1974-04-18
4 680919301301 1968-09-19
5 730302301686 1973-03-02
6 600727300553 1960-07-27
7 710404301805 1971-04-04
8 661210301930 1966-12-10
9 691025401917 1969-10-25
10 930513351265 1993-05-13
11 750618300709 1975-06-18
12 731010301512 1973-10-10
13 780315300370 1978-03-15
14 650704300130 1965-07-04
15 901006351464 1990-10-06
16 650611300690 1965-06-11
17 790830401008 1979-08-30
18 880525401338 1988-05-25
19 680101400668 1968-01-01
20 600308400773 1960-03-08
21 860220402979 1986-02-20
22 760916300027 1976-09-16
23 811319300910 TOO
24 620365302226 TOO
Что делает функция?
- Принимает на вход число.
- Переводит в строку.
- Берет только первые 6 символов.
- Переводит в формат datetime.
- От данной даты берем только дату.
- Если данная дата больше, чем текущая (то есть сегодня), вычитаем 100 лет, приводя ее к нормальному формату (то есть, чтобы не было дат вида 2023 год, 2054 и т.д.)
- Если данная дата не больше текущей, то оставляем как есть.
- Пользуясь try-except, если невозможно перевести входное число в дату и выскакивает ошибка - то присваиваем TOO