当遇到”DataFrame.dtypes for data must be int, float or bool”报错时,直接原因是你的时间数据列类型不是数值类型,需要先将其转换为int或float,再使用pd.to_datetime进行转换。
int转时间报错:DataFrame.dtypes must be int, float or bool 原因分析
这个报错信息来自pandas库,在调用pd.to_datetime时触发,它要求传入的数据必须是数值类型,但很多情况下时间戳列由于包含空值、字符串或混合类型,被pandas识别为object,导致转换失败。
常见错误场景
- 从CSV或Excel导入时间戳时,列中混入了空字符串或非数字字符,整列类型变为object。
- 时间戳是字符串形式的整数,1609459200″,直接传入pd.to_datetime。
- 数据中虽有数字,但存在缺失值或NaN,且类型为float64,这本身不会报错,但如果缺失值以字符串”NaN”形式存在,就会变成object。
- 使用了unit参数(如unit=’s’),但数据不是数值类型,pandas无法判断单位。
如何确认数据类型
用df.dtypes查看时间列,如果显示object,就需要转换,更细粒度可以用df[‘col’].apply(type).value_counts(),查看每个元素的具体类型分布。
pandas时间戳转换错误:秒转日期时间的正确方法
解决这个报错只需三步:清洗、类型转换、时间转换,下面从秒时间戳转换开始说明。
第一步:强制转换为数值类型
使用pd.to_numeric,将字符串或混合类型统一转为float64,非法值变为NaN。
df['timestamp'] = pd.to_numeric(df['timestamp'], errors='coerce')
- errors=’coerce’将无法转换的变为NaN,保留数值部分。
- 如果数据中全是整数,后续可以用astype(int)进一步转换,但通常float64也能满足时间转换需求。
第二步:处理缺失值
pd.to_datetime默认遇到NaN会报错,除非设置errors=’coerce’,建议先选择保留或填充。
df = df.dropna(subset=['timestamp']) # 丢弃 # 或 df['timestamp'].fillna(0, inplace=True) # 填充为0
第三步:转换时间
df['datetime'] = pd.to_datetime(df['timestamp'], unit='s')
完整示例
假设你有一个日志文件,时间戳列是字符串形式的秒数。
import pandas as pd
df = pd.read_csv('log.csv')
print(df['time'].dtype) # object
df['time'] = pd.to_numeric(df['time'], errors='coerce')
df = df.dropna(subset=['time'])
df['time'] = df['time'].astype(int)
df['datetime'] = pd.to_datetime(df['time'], unit='s')
实操步骤:处理毫秒和微秒时间戳
毫秒时间戳
如果时间戳是13位毫秒,unit=’ms’即可,注意数值可能超过int32范围,建议用float64或int64。
df['timestamp'] = pd.to_numeric(df['timestamp'], errors='coerce') df['datetime'] = pd.to_datetime(df['timestamp'], unit='ms')
微秒时间戳
16位微秒,unit=’us’。
混合单位场景
如果数据来源不同,时间戳单位不一致,可以先统一单位,将所有秒时间戳乘以1000转为毫秒,再统一转换,但更可靠的做法是:判断数值范围,写一个自定义函数。
def convert_to_datetime(series):
max_val = series.max()
if max_val > 1012: # 毫秒或微秒
# 进一步判断
unit = 'ms' if max_val < 1015 else 'us'
else:
unit = 's'
return pd.to_datetime(series, unit=unit)
如何避免这个报错:数据预处理的最佳实践
在读取时指定类型
在pd.read_csv中直接指定dtype,避免类型被推断为object。
df = pd.read_csv('data.csv', dtype={'timestamp': 'float64'})
使用astype直接转换
如果确定数据全是数字字符串,可以用astype(int)或astype(float)。
df['timestamp'] = df['timestamp'].astype(float)
行业共识:先清洗后转换
业内专家指出,大部分时间处理错误源于数据质量,而非函数本身,在进入pd.to_datetime之前,花30秒检查数据类型,能节省大量调试时间。
表格对比:不同时间戳单位转换参数
| 时间戳位数 | 常见单位 | 转换参数 | 示例值 |
|---|---|---|---|
| 10位 | 秒 | unit=’s’ | 1609459200 |
| 13位 | 毫秒 | unit=’ms’ | 1609459200000 |
| 16位 | 微秒 | unit=’us’ | 1609459200000000 |
| 19位 | 纳秒 | unit=’ns’ | 1609459200000000000 |
注意:pandas默认使用纳秒,如果时间戳单位是秒但没有指定unit,会得到错误结果,所以必须显式指定unit参数。
其他相关报错与联系
与”Unknown string format” 报错区别
“Unknown string format” 发生在数据是字符串格式的日期(如”2021-01-01″)时,但你没有指定format或数据格式不一致,而本错误专门针对数值类型要求。
与pd.to_timedelta的关系
pd.to_timedelta同样需要数值类型,错误信息类似,解决方法相同。
Q&A 关于int转时间报错的常见问题
问题1:我的时间戳列显示int64,为什么还会报这个错?
回答: 如果你的列类型是int64,原则上不会报这个错,请检查列名是否正确,或者是否在操作中无意中改变了类型,常见情况是:你使用了类似df[‘timestamp’] = df[‘timestamp’].astype(str)进行了转换,建议用df.dtypes确认当前列类型。
问题2:pd.to_numeric之后,转换时间还是报错”cannot convert float NaN to integer”?
回答: 这是因为pd.to_numeric产生的NaN在后续astype(int)时会失败,解决方案:不要先转int,直接用float时间戳配合pd.to_datetime,它支持float,如果一定要转int,先用fillna或dropna处理NaN。
问题3:时间戳是13位数字,但转出来的时间总是1970年,怎么办?
回答: 13位数字通常代表毫秒,但如果你用unit=’s’,会被当作秒,导致结果在1970年附近,正确做法是使用unit=’ms’,如果不确定单位,可以计算时间戳的范围:如果数值在10^12量级,通常是毫秒;在10^9量级是秒。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/556625.html




