使用pd.to_datetime()时.loc赋值未转为datetime64[ns]问题咨询
Pandas中.loc赋值无法转换列类型的问题
我在使用Pandas的pd.to_datetime()函数时遇到一个奇怪的问题:用.loc方法尝试将DataFrame的"datetime"列转换为datetime64[ns]类型时,该列仍然保持object类型;但直接用方括号[]赋值时,就能成功转换类型。
不生效的代码版本
df.loc[:, "datetime"] = pd.to_datetime(df["datetime"]) print(df.dtypes) ####### Results ####### id int64 testcolumn object datetime object value object
生效的代码版本(生成新列)
df.loc[:, "foo"] = pd.to_datetime(df["datetime"]) print(df.dtypes) ####### Results ####### id int64 testcolumn object datetime object value object foo datetime64[ns]
同样生效的代码版本
df["datetime"] = pd.to_datetime(df["datetime"]) print(df.dtypes) ####### Results ####### id int64 testcolumn object datetime datetime64[ns] value object
我困惑的是为何第一个使用.loc的代码无法正确转换类型,而第二个可以。两者仅赋值方式不同。希望有人解释原因,或提供用.loc转换的替代方法。
最小可复现示例(MVCE)
import pandas as pd # version: '2.0.1' # Sample data for the DataFrame data = { 'id': [1, 2, 3], 'testcolumn': ['A', 'B', 'C'], 'datetime': ['2023-07-25 10:30:00', '2023-07-26 12:45:00', '2023-07-27 15:15:00'], 'value': ['100', '200', '300'] } # Create the DataFrame df = pd.DataFrame(data) df.loc[:, "datetime"] = pd.to_datetime(df["datetime"]) print(df.dtypes) df.loc[:, "foo"] = pd.to_datetime(df["datetime"]) print(df.dtypes) df["datetime"] = pd.to_datetime(df["datetime"]) print(df.dtypes)
原因分析
这是Pandas的类型推断与赋值机制导致的差异:
- 当使用
.loc对已存在的列赋值时,Pandas会优先保留原列的dtype。如果原列是object类型,Pandas会将转换后的datetime对象强制转回object类型存入,默认认为你要在原有列的类型框架内修改数据。 - 直接用方括号
df["datetime"] = ...属于列整体替换操作,会完全覆盖原列的类型定义,直接采用新赋值数据的datetime64[ns]类型。 - 用
.loc创建新列时,因为没有原类型的约束,Pandas会自动识别新数据的类型并设置为datetime64[ns]。
用.loc转换原列的替代方案
方案1:先删除原列,再用.loc重新添加
# 先删除原object类型的列 df.drop("datetime", axis=1, inplace=True) # 用原始数据重新解析后添加 df.loc[:, "datetime"] = pd.to_datetime(data["datetime"])
方案2:先修改列的dtype,再用.loc赋值
# 先将列的类型设置为datetime64[ns] df["datetime"] = df["datetime"].astype("datetime64[ns]") # 再用.loc赋值(此时类型已被修改,不会强制转回object) df.loc[:, "datetime"] = pd.to_datetime(df["datetime"])
方案3:结合.astype强制指定类型赋值
df.loc[:, "datetime"] = pd.to_datetime(df["datetime"]).astype("datetime64[ns]")
方案4:使用df.assign()间接实现(等价于整体替换)
df = df.assign(datetime=pd.to_datetime(df["datetime"]))
内容的提问来源于stack exchange,提问作者Bodydrop
相关产品推荐
相关产品推荐

