Pandas中Timestamp与str比较报错,求日期十年分段归类方案
问题分析与解决
错误根源
- 类型不兼容:你将
Timestamp类型的日期和字符串格式的日期直接比较,Pandas不支持跨类型的时间比较,因此抛出<not supported between instances of 'Timestamp' and 'str'>错误。 - 变量名混乱:初始化的列表是
cat_date,但循环中错误使用了未定义的cat_lft、cat_dt变量,最终赋值给df["Year"]的是空列表,会导致数据缺失甚至变量未定义报错。 - 分支变量错误:最后else分支里的
cat_dt从未定义,且用字符串"nan"不如Pandas原生的pd.NA规范。
修复方案
方案1:修正原循环逻辑
把用于比较的字符串日期转换为datetime对象,统一变量名:
import pandas as pd # 示例数据 data = {'Event': [0,1,2,3], 'Event.Date': ['1961-10-24','1972-07-19','1989-08-02','2022-12-26']} df = pd.DataFrame(data) # 转换为datetime类型 df['Event.Date'] = pd.to_datetime(df['Event.Date']) cat_date = [] # 预定义转换后的比较日期 compare_dates = { '1950s_cutoff': pd.to_datetime('1960-01-01'), '1960s_cutoff': pd.to_datetime('1970-01-01'), '1970s_cutoff': pd.to_datetime('1980-01-01'), '1980s_cutoff': pd.to_datetime('1990-01-01'), '1990s_cutoff': pd.to_datetime('2000-01-01'), '2000s_cutoff': pd.to_datetime('2010-01-01'), '2010s_cutoff': pd.to_datetime('2023-01-01') } for dt in df["Event.Date"]: if dt < compare_dates['1950s_cutoff']: cat_date.append("1950's") elif dt < compare_dates['1960s_cutoff']: cat_date.append("1960's") elif dt < compare_dates['1970s_cutoff']: cat_date.append("1970's") elif dt < compare_dates['1980s_cutoff']: cat_date.append("1980's") elif dt < compare_dates['1990s_cutoff']: cat_date.append("1990's") elif dt < compare_dates['2000s_cutoff']: cat_date.append("2000's") elif dt < compare_dates['2010s_cutoff']: cat_date.append("2010's") else: cat_date.append(pd.NA) df["Year"] = cat_date
方案2:高效向量化处理(推荐)
避免循环,利用Pandas向量化操作快速生成区间标签,适合大数据量场景:
import pandas as pd # 示例数据 data = {'Event': [0,1,2,3], 'Event.Date': ['1961-10-24','1972-07-19','1989-08-02','2022-12-26']} df = pd.DataFrame(data) df['Event.Date'] = pd.to_datetime(df['Event.Date']) # 自定义区间和对应标签 time_bins = [pd.to_datetime('1950-01-01'), pd.to_datetime('1960-01-01'), pd.to_datetime('1970-01-01'), pd.to_datetime('1980-01-01'), pd.to_datetime('1990-01-01'), pd.to_datetime('2000-01-01'), pd.to_datetime('2010-01-01'), pd.to_datetime('2023-01-01'), pd.to_datetime('2100-01-01')] decade_labels = ["1950's", "1960's", "1970's", "1980's", "1990's", "2000's", "2010's", "2020's"] df['Year'] = pd.cut(df['Event.Date'], bins=time_bins, labels=decade_labels, include_lowest=True)
如果不需要自定义区间(比如2022直接归为2020's),可以用更简洁的年份计算:
df['Year'] = (df['Event.Date'].dt.year // 10 * 10).astype(str) + "'s"
最终效果
两种方案都能生成你需要的结果:
| Event | Event.Date | Year |
|---|---|---|
| 0 | 1961-10-24 | 1960's |
| 1 | 1972-07-19 | 1970's |
| 2 | 1989-08-02 | 1980's |
| 3 | 2022-12-26 | 2010's |
内容的提问来源于stack exchange,提问作者Maxim
相关产品推荐
相关产品推荐

