Pandas匹配两列最近Datetime值时遭遇integer/long类型错误
我来帮你梳理下之前两种方法的问题,再给出可靠的解决方案:
先分析你遇到的错误原因
第一种方法(truncate)的问题
truncate() 方法是针对DataFrame/Series的索引进行截断的,而你直接对D1['Date']这个Series调用它时,它的索引是默认的整数索引(0,1,2...),你传入的ICO_to是Timestamp类型,整数索引和Timestamp无法直接比较,所以才会抛出TypeError: Cannot compare type 'Timestamp' with type 'long'。
第二种方法(get_loc)的问题
index.get_loc() 是根据索引的值来查找位置,你的DataFrame默认索引是整数,不是DatetimeIndex,所以传入datetime对象肯定会报错要求整数,这就是TypeError: an integer is required的原因。
正确的解决方案
首先确保日期列都转换为datetime类型(你已经做了这步,这里再确认下):
import pandas as pd import datetime # 转换日期列类型 D1['Date'] = pd.to_datetime(D1['Date']) D1['ICO_to'] = pd.to_datetime(D1['ICO_to']) # 提取目标日期(因为ICO_to列所有值相同) target_date = D1['ICO_to'].iloc[0]
方法1:计算时间差绝对值找最接近的日期(最直观,无需修改索引)
这种方法不管目标日期在Date列的前后,都能找到最匹配的那个值:
# 计算每个Date与目标日期的时间差绝对值 time_diffs = abs(D1['Date'] - target_date) # 找到时间差最小的那一行对应的Date值 closest_date = D1.loc[time_diffs.idxmin(), 'Date']
针对你的示例数据,target_date是2017-05-30,Date列里有2017-05-30 18:00:00,这就是完全匹配的,所以这个方法会直接返回这个值。
方法2:先将Date设为索引,再用truncate或get_loc(适合需要筛选前后日期的场景)
如果你想专门找不早于目标日期的最早日期,或者不晚于目标日期的最晚日期,可以先把Date设为索引:
# 将Date列设为索引 D1_indexed = D1.set_index('Date') # 用truncate找不早于目标日期的最早行 truncated_after = D1_indexed.truncate(before=target_date) first_date_after_target = truncated_after.index[0] # 用get_loc结合method='nearest'找最接近的日期索引 closest_idx = D1_indexed.index.get_loc(target_date, method='nearest') closest_date_via_index = D1_indexed.index[closest_idx]
这样就不会出现之前的类型错误了,因为此时索引是DatetimeIndex,和target_date类型一致,可以正常比较。
方法3:筛选完全匹配日期的行(如果需要严格匹配日期部分)
如果你的Date列包含时分秒,而ICO_to只有日期,想找日期部分完全一致的行:
# 筛选Date的日期部分等于目标日期的行 matched_rows = D1[D1['Date'].dt.date == target_date.date()] if not matched_rows.empty: # 如果有匹配的行,取第一个(或任意一个) closest_date = matched_rows['Date'].iloc[0] else: # 没有完全匹配的,再用时间差找最接近的 time_diffs = abs(D1['Date'] - target_date) closest_date = D1.loc[time_diffs.idxmin(), 'Date']
内容的提问来源于stack exchange,提问作者Cole Starbuck

