我有一个数据框,其中有一列称为日期。该列包含两种不同格式的日期:8/05/2022 和 Excel 序列日期 (44882)。我需要将 Excel 序列日期转换为另一种格式,而不影响列中存在的实际日期。我该怎么办?
import pandas as pd
import datetime as dt
def date_serial_number(serial_number: int) -> dt.datetime:
delta = dt.datetime(1899, 12, 30) + dt.timedelta(days=serial_number)
return delta
customer_data['date'] = customer_data['invoice_date'].apply(
lambda x: pd.to_datetime(x, errors='coerce') if isinstance(x, str) else date_serial_number(x)
)
print(customer_data)
它将 44882 转换为 Nat。
当前设置的问题是 pd.to_datetime 函数尝试将invoice_date 列中的所有值更改为日期时间。当它遇到 Excel 序列日期(不是字符串)时,它会失败并返回 NaT。
要解决此问题,您可以使用更精确的方法来查看发票日期列中每个值的类型。如果该值是一个字符串(代表常规日期),它将使用 pd.to_datetime 更改为日期时间。如果该值是整数或小数(代表 Excel 序列日期),它将使用自定义 date_serial_number 函数进行更改。执行此操作的方法如下:
import pandas as pd
import datetime as dt
# Function to convert Excel serial number to datetime
def date_serial_number(serial_number: int) -> dt.datetime:
# Excel serial dates start from 1899-12-30, not 1900-01-01
return dt.datetime(1899, 12, 30) + dt.timedelta(days=serial_number)
# Sample data
data = {
'invoice_date': ['8/05/2022', 44882, '12/01/2021', 44890]
}
# Create DataFrame
customer_data = pd.DataFrame(data)
# Apply conversion
customer_data['invoice_date'] = customer_data['invoice_date'].apply(
lambda x: pd.to_datetime(x, errors='coerce') if isinstance(x, str) else date_serial_number(x)
)
print(customer_data)
此代码会将 Excel 序列日期转换为正确的日期时间格式,而不更改列中的其他日期。结果看起来有点像这样:
invoice_date
0 2022-08-05
1 2022-11-01
2 2021-12-01
3 2022-11-09