You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何pandas.apply遍历Date列时首次返回DatetimeIndex而非Timestamp?

Pandas Date列apply时首次返回DatetimeIndex的原因解析

当前问题

现有如下Pandas DataFrame:

>>> print(my_df)
                        Date   Revenue
0  2023-12-27 00:00:00-05:00   3880359
1  2023-12-26 00:00:00-05:00   3139100
2  2023-12-22 00:00:00-05:00   2849700
3  2023-12-21 00:00:00-05:00   4884800
4  2023-12-20 00:00:00-05:00   4032200
5  2023-12-19 00:00:00-05:00   4979100
6  2023-12-18 00:00:00-05:00   6314700
7  2023-12-15 00:00:00-05:00  11503000
8  2023-12-14 00:00:00-05:00   8033300
9  2023-12-13 00:00:00-05:00   7727900

遍历Revenue列时结果符合预期:

>>> my_df['Revenue'].apply(lambda x: print(x, type(x)))
3880359 <class 'int'>
3139100 <class 'int'>
2849700 <class 'int'>
4884800 <class 'int'>
4032200 <class 'int'>
4979100 <class 'int'>
6314700 <class 'int'>
11503000 <class 'int'>
8033300 <class 'int'>
7727900 <class 'int'>

但遍历Date列时出现异常,首次迭代返回了DatetimeIndex对象:

>>> my_df['Date'].apply(lambda x: print(x, type(x)))
DatetimeIndex(['2023-12-27 00:00:00-05:00', '2023-12-26 00:00:00-05:00', '2023-12-22 00:00:00-05:00', '2023-12-21 00:00:00-05:00', '2023-12-20 00:00:00-05:00', '2023-12-19 00:00:00-05:00', '2023-12-18 00:00:00-05:00', '2023-12-15 00:00:00-05:00', '2023-12-14 00:00:00-05:00', '2023-12-13 00:00:00-05:00'], dtype='datetime64[ns, America/New_York]', freq=None) <class 'pandas.core.indexes.datetimes.DatetimeIndex'>
2023-12-27 00:00:00-05:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>
2023-12-26 00:00:00-05:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>
2023-12-22 00:00:00-05:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>
2023-12-21 00:00:00-05:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>
2023-12-20 00:00:00-05:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>
2023-12-19 00:00:00-05:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>
2023-12-18 00:00:00-05:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>
2023-12-15 00:00:00-05:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>
2023-12-14 00:00:00-05:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>
2023-12-13 00:00:00-05:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>

为何会出现这种情况?首次迭代为何返回索引对象?

重现步骤

  1. 创建example.json文件,内容如下:
{"Date":{"0":1703653200000,"1":1703566800000,"2":1703221200000,"3":1703134800000,"4":1703048400000,"5":1702962000000,"6":1702875600000,"7":1702616400000,"8":1702530000000,"9":1702443600000},"Revenue":{"0":3880359,"1":3139100,"2":2849700,"3":4884800,"4":4032200,"5":4979100,"6":6314700,"7":11503000,"8":8033300,"9":7727900}}
  1. 创建example.py文件,内容如下:
import pandas as pd

# 假设example.json和脚本在同一目录
file_path = 'example.json'

# 读取JSON生成DataFrame
df = pd.read_json(file_path)

# 打印DataFrame
print(df)

# 复现问题
df['Date'].apply(lambda x: print(x, type(x)))

原因分析

核心问题在于pd.read_json的默认行为:当读取包含时间戳的JSON时,它会自动将Date列解析为DatetimeIndex(数据框的索引),而不是常规的Series列。此时调用df['Date']获取的是DatetimeIndex对象,而非Series。

apply方法在DatetimeIndex上的执行逻辑和Series不同:

  • 对Series执行apply,会逐元素传递单个值(比如int或Timestamp)
  • 对DatetimeIndex执行apply,会先将整个索引对象作为第一个参数传入lambda,之后再逐元素传递每个Timestamp值

你可以通过以下代码验证这一点:

print(type(df['Date']))  # 输出 <class 'pandas.core.indexes.datetimes.DatetimeIndex'>

解决方法

方法1:读取时禁用自动日期转换

读取JSON时指定convert_dates=False,之后手动将时间戳转换为带时区的Timestamp列:

df = pd.read_json(file_path, convert_dates=False)
df['Date'] = pd.to_datetime(df['Date'], unit='ms').dt.tz_localize('America/New_York')

此时df['Date']是Series类型,apply会逐元素传递Timestamp。

方法2:将DatetimeIndex转换为Series后再使用apply

如果不想修改读取逻辑,可以先把DatetimeIndex转为Series:

df['Date'].to_series().apply(lambda x: print(x, type(x)))

内容的提问来源于stack exchange,提问作者AlanSTACK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 09:05:59