pandas DataFrame按时间范围及值条件替换值的实现与报错解决
报错核心原因
- 链式赋值逻辑缺陷:代码
df = df[df.between_time('06:00', '20:00')].replace([0,1,2,3], np.nan, inplace=True)会先筛出符合时间范围的DataFrame子集,对该子集调用带inplace=True的replace方法后,方法返回值为None,会直接把原变量df覆盖为None,丢失原有数据结构,后续执行布尔条件校验时自然会抛出需要布尔数组、但拿到对象类型的报错。 - 方法使用前提不满足:
between_time是Pandas专门为datetime索引设计的切片方法,要求调用对象的索引必须是时间类型,当前代码中datetime是普通数据列而非索引,直接调用无法生成合法的筛选布尔数组,触发参数校验失败。
需求实现方案
目标为替换06:00-20:00时间段内、vehicles列值≤3的数值为NaN,提供两种适配不同使用场景的实现方式:
方案1:基于时间索引实现,适配高频时间切片场景
import pandas as pd import numpy as np # 将datetime列设为时间索引(已完成索引设置可跳过该步骤) df = df.set_index('datetime') # 生成时间范围筛选的位置索引 time_pos_mask = df.index.indexer_between_time('06:00', '20:00') # 生成数值满足要求的布尔掩码 value_mask = df['vehicles'] <= 3 # 对同时满足两个条件的位置赋值为NaN df.iloc[time_pos_mask, df.columns.get_loc('vehicles')][value_mask.iloc[time_pos_mask]] = np.nan
方案2:不修改原索引结构,逻辑通用
# 从datetime列提取每行对应的时分时间部分 time_col = df['datetime'].dt.time # 定义时间边界 start_time = pd.to_datetime('06:00').time() end_time = pd.to_datetime('20:00').time() # 合并三个筛选条件生成总掩码:时间在范围内 + 数值≤3 total_mask = (time_col >= start_time) & (time_col <= end_time) & (df['vehicles'] <= 3) # 直接按掩码执行替换 df.loc[total_mask, 'vehicles'] = np.nan
内容的提问来源于stack exchange,提问作者yarvis
相关产品推荐
相关产品推荐

