Я хочу прочитать CSV-файл и преобразовать значение последовательного времени Excel в строку YYYY-MM-DD. Файл выглядит так:
A B start_date
0 yes 42736
1 no 42751
2 yes 43039
Функция, которую я хочу использовать в качестве преобразователя:
def convert_excel_time(excel_time):
return (pd.to_datetime('1900-01-01') + pd.to_timedelta(excel_time,unit='day')).strftime("%Y-%m-%d")
И я использую это так:
data = pd.read_csv("data.csv",encoding = "ISO-8859-1",
converters = {'start_date': convert_excel_time})
При использовании функции в качестве автономной я получаю правильный результат:
excel_time = 42736
In[1]: (pd.to_datetime('1900-01-01')+pd.to_timedelta(excel_time,unit='day')).strftime("%Y-%m-%d")
Out[1]: '2017-01-03'
Однако, если я использую эту функцию в качестве конвертера при чтении CSV-файла, все мои даты начала будут «1900-01-01». Что я делаю неправильно?
Это точно! Но почему он работает нормально в изоляции? Почему кастинг переменной excel_time несовместим? NB, вы можете записать это как правильный ответ для использования другими.






По умолчанию python имеет тенденцию читать файлы как строки. Обычно он делает это, если вы не скажете ему поступить иначе. Я не особенно знаком с тем, как pandas работает, но, похоже, здесь происходит именно это: когда pd.read_csv() читает ваш файл, он интерпретирует столбец start_date как строки.
документация для pd.to_timedelta() говорит, что он должен нормально читать строки. Но когда вы на самом деле тестируете метод, кажется, что в этом конкретном случае он не работает.
>>> pd.to_timedelta(44, "day")
Timedelta('44 days 00:00:00')
>>> pd.to_timedelta("44", "day")
Timedelta('0 days 00:00:00.000000')
Я подозреваю, что когда он перечисляет str в качестве допустимого аргумента, он ссылается на строковое представление TimeDelta, а не на int-as-a-str. И по какой-то причине вместо того, чтобы вызвать ошибку, он просто возвращает нулевое значение, когда это дается.
Следовательно, вам просто нужно убедиться, что вы передаете int вместо str. Самый простой способ сделать это — просто указать excel_time в начале функции convert_excel_time():
def convert_excel_time(excel_time):
excel_time = int(excel_time)
return (pd.to_datetime('1900-01-01') + pd.to_timedelta(excel_time,unit='day')).strftime("%Y-%m-%d")
При фактическом чтении данных pandas, кажется, предоставляет механизм, позволяющий избежать этой проблемы: dtype kwarg для pd.read_csv() позволяет вам указать ожидаемый тип каждого столбца (по-видимому, по умолчанию используется str). Проблема в том, что если вы дадите converters kwarg, вместо него будет применен он, поэтому вам придется заниматься преобразованием самостоятельно.
Он может интерпретировать
start_dateкак строку, а не как целое число, и это может привести к путанице. Попробуйте поставитьexcel_time = int(excel_time)в начале вашей функцииconvert_excel_time()и посмотрите, исправит ли это проблему.