Pandas处理日期遇NaTType与KeyError问题求解决方案
解决Pandas处理币安K线数据的两类错误
问题概述
处理币安K线数据时遇到两个核心错误:
- 执行日期格式化
df['Date'].max().strftime("%Y-%m-%d %H:%M:%S")触发ValueError: NaTType does not support strftime - 调用
dropna(subset=['Date'])移除缺失值时出现KeyError: ['Date']
错误1:KeyError: ['Date']的原因与修复
原因
你之前的代码中先执行了df.set_index('Date', inplace=True),将Date列设置为DataFrame的索引,此时Date不再是普通数据列,后续调用dropna(subset=['Date'])自然找不到该列,触发KeyError。
修复方案
如果要使用between_time方法,可调整顺序:先过滤时间范围,再重置索引;或者直接用列过滤(如你当前代码的逻辑)。若坚持用索引方式,修改代码如下:
df.set_index('Date', inplace=True) df = df.between_time(TIME_BINANCE_OPEN, TIME_BINANCE_CLOSE) # Date是索引,无需再指定subset=['Date'],直接重置索引即可 df.reset_index(inplace=True)
错误2:ValueError: NaTType does not support strftime的原因与修复
原因
即使执行了dropna(subset=['Date']),仍可能出现两种情况:
pd.to_datetime(df['Date'])将无效日期转换为NaT,后续时间过滤后剩余数据的Date列全为NaT- 过滤后DataFrame非空,但
Date列无有效值,调用max()返回NaT,再执行strftime就会报错
修复方案
- 转换日期时处理无效值,提前过滤缺失项:
# 转换日期并将无效值转为NaT df['Date'] = pd.to_datetime(df['Date'], errors='coerce') # 先移除Date列的缺失值,再做时间范围过滤 df = df.dropna(subset=['Date'])
- 在格式化日期前,额外检查
Date列是否存在有效值:
if not df.empty and df['Date'].notna().any(): max_recent_date = df['Date'].max().strftime("%Y-%m-%d %H:%M:%S") min_recent_date = df['Date'].min().strftime("%Y-%m-%d %H:%M:%S") else: min_recent_date = max_recent_date = None
完整修正后的代码
for symbol in stocks_list: print("Starting data fetching process Stock: ", symbol) df = get_binance_bars(symbol, interval, START_DATE, END_DATE) print("Data fetching process completed df.shape: ", df.shape) print(df) print(df.columns) if df is not None and not df.empty: # 转换日期并处理无效值 df['Date'] = pd.to_datetime(df['Date'], errors='coerce') # 先移除Date列缺失值 df = df.dropna(subset=['Date']) if not df.empty: TIME_BINANCE_OPEN = pd.to_datetime("00:01:00").time() TIME_BINANCE_CLOSE = pd.to_datetime("08:19:00").time() # 时间范围过滤 df = df[(df['Date'].dt.time >= TIME_BINANCE_OPEN) & (df['Date'].dt.time <= TIME_BINANCE_CLOSE)] # 检查是否有有效日期 if df['Date'].notna().any(): max_recent_date = df['Date'].max().strftime("%Y-%m-%d %H:%M:%S") min_recent_date = df['Date'].min().strftime("%Y-%m-%d %H:%M:%S") else: min_recent_date = max_recent_date = None else: min_recent_date = max_recent_date = None directory = "d_price/RAW_binance/" if not os.path.exists(directory): os.makedirs(directory) file_path = directory + "binance_" + symbol + '_' + interval + ".csv" df.to_csv(file_path, sep="\t", index=None) # 打印时处理可能的NaT情况 start_date = str(df['Date'].min()) if not df.empty and df['Date'].notna().any() else "N/A" end_date = str(df['Date'].max()) if not df.empty and df['Date'].notna().any() else "N/A" print(f"\tSTART: {start_date} END: {end_date} shape: {df.shape}\n")
内容的提问来源于stack exchange,提问作者Angela
相关产品推荐
相关产品推荐

