Многоформатный строковый столбец для преобразования в формат даты

У меня есть столбец, который представляет дату, но отформатирован как строка. Я не могу использовать простой pandas.to_datetime, например:

01/02/2023
Apr 02, 2016
Jun 2021
2023/12/01

Я попытался создать приведенную ниже формулу, в которой я бы перечислил возможные форматы даты и использовал цикл for для преобразования столбца в желаемый формат. Однако это явно неправильно, так как столбец содержит NONE после его применения. Не могли бы вы посоветовать мне лучшее направление или что я должен изменить, пожалуйста?

def DateFormat(data):
    for fmt in ('%b %d, %Y', '%d/%m/%Y', '%b %Y', '%Y/%b/%d'):
        try:
            pd.to_datetime(data['date'], format=fmt)
            
        except ValueError:
            pass


data['date'] =  data.apply(DateFormat, axis = 1)

ПЕРЕД ПРИМЕНЕНИЕМ DateFormat: | ID | Дата | | --- | -------------- | | 1 | 02.01.2023 | | 2 | 02 апреля 2016 г. | | 3 | июнь 2021 г. | | 4 | 01.12.2023 |

ПОСЛЕ ПРИМЕНЕНИЯ DateFormat: | ID | Дата | | --- | ----- | | 1 | Нет | | 2 | Нет | | 3 | Нет | | 4 | Нет |

вы должны использовать return pd.to_datetime(...) для выхода из функции, когда она конвертируется без проблем

furas 20.03.2022 08: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 может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
35
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Если вы не используете return для возврата значения, то он использует return None в конце функции.

Вы должны использовать return pd.to_datetime(...)

И если вы хотите вернуть исходное значение, когда оно не может его преобразовать, вам нужно return в конце. ИЛИ вы можете использовать return, чтобы вернуть значение по умолчанию.

def DateFormat(data):
    for fmt in ('%b %d, %Y', '%d/%m/%Y', '%b %Y', '%Y/%b/%d'):
        try:
            return pd.to_datetime(data['date'], format=fmt)
        except ValueError:
            pass

    # return original `date` if it couldn't convert
    return data['date']

    # or return some default value
    #return datetime.datetime(1900, 1, 1)

Обновлено:

Минимальный рабочий код.

Я также добавил код из ответа @Corralien, и он также работает для этих данных.

import pandas as pd

# --- functions ---
    
def parse_date(row):
    # I had to add `'%Y/%m/%d'`
    for fmt in ('%b %d, %Y', '%d/%m/%Y', '%b %Y', '%Y/%b/%d', '%Y/%m/%d'):
        try:
            return pd.to_datetime(row['date'], format=fmt)
        except ValueError:
            pass

# --- main ---

data = pd.DataFrame({
    'date': ['01/02/2023', 'Apr 02, 2016', 'Jun 2021', '2023/12/01']
})
        
data['new_date_1'] = data.apply(parse_date, axis=1)

data['new_date_2'] = pd.to_datetime(data['date'], dayfirst=True)

print(data)

Результат:

           date new_date_1 new_date_2
0    01/02/2023 2023-02-01 2023-02-01
1  Apr 02, 2016 2016-04-02 2016-04-02
2      Jun 2021 2021-06-01 2021-06-01
3    2023/12/01 2023-12-01 2023-12-01

Почему бы не позволить Pandas вывести ваш формат даты и времени? и установите dayfirst=True для формата первого свидания (%d/%m/%Y)

df['Date'] = pd.to_datetime(df['Date'], dayfirst=True)
print(df)

# Output
   ID       Date
0   1 2023-02-01
1   2 2016-04-02
2   3 2021-06-01
3   4 2023-12-01

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