Панды: преобразователь времени работает изолированно, но не при чтении CSV-файла

Я хочу прочитать 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». Что я делаю неправильно?

Он может интерпретировать start_date как строку, а не как целое число, и это может привести к путанице. Попробуйте поставить excel_time = int(excel_time) в начале вашей функции convert_excel_time() и посмотрите, исправит ли это проблему.

Green Cloak Guy 02.07.2019 16:24

Это точно! Но почему он работает нормально в изоляции? Почему кастинг переменной excel_time несовместим? NB, вы можете записать это как правильный ответ для использования другими.

Zizzipupp 02.07.2019 16:26
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
2
45
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

По умолчанию 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, вместо него будет применен он, поэтому вам придется заниматься преобразованием самостоятельно.

Другие вопросы по теме