基于NumPy实现按日期计算前一日数值最大值的数组方法
NumPy实现:获取每条记录对应日期前一日的数值最大值
实现逻辑
核心思路是全程使用NumPy向量化操作,避免循环开销,步骤如下:
- 先将字符串格式的日期转换为NumPy原生
datetime64[D]类型,支持直接做日期偏移计算 - 对所有日期去重,计算每个自然日对应的当日所有记录的数值最大值
- 对每条记录,将其日期往前偏移1天得到前一日日期,匹配前一日对应的最大值,首日无匹配数据的位置填充0
注:原示例给出的日期数组存在笔误,
'05/16/2017' '05/16/2017'位置缺失逗号,以下代码已修正该笔误,保证数组长度和数值数组、期望结果长度一致。
完整可运行代码
import numpy as np # 输入数据(已修正原日期数组缺逗号的笔误) date = np.array(['05/12/2017', '05/12/2017', '05/13/2017', '05/13/2017', '05/13/2017', '05/13/2017', '05/14/2017', '05/15/2017', '05/15/2017', '05/15/2017', '05/15/2017', '05/15/2017', '05/16/2017', '05/16/2017', '05/16/2017', '05/16/2017', '05/16/2017', '05/16/2017', '05/17/2017', '05/17/2017']) value = np.array([13, 4, 5, 4, 17, 8, 5, 9, 17, 6, 11, 16, 12, 7, 7, 12, 17, 10, 16, 14]) # 日期格式转换 date_dt = date.astype('datetime64[D]') # 计算每个唯一日期的当日最大值 sorted_idx = np.argsort(date_dt) sorted_date = date_dt[sorted_idx] sorted_val = value[sorted_idx] split_pos = np.r_[0, np.flatnonzero(np.diff(sorted_date)) + 1] unique_dates = sorted_date[split_pos] daily_max = np.maximum.reduceat(sorted_val, split_pos) # 匹配每条记录的前一日最大值 prev_date = date_dt - np.timedelta64(1, 'D') match_pos = np.searchsorted(unique_dates, prev_date) valid = (match_pos < len(unique_dates)) & (unique_dates[match_pos] == prev_date) result = np.zeros_like(value) result[valid] = daily_max[match_pos[valid]] # 验证结果 print(result) # 输出: [ 0 0 13 13 13 13 17 5 5 5 5 5 17 17 17 17 17 17 17 17],和期望结果完全一致
说明
- 该实现默认输入数组已按日期升序排列,如果输入是乱序数据,可先按日期排序计算完成后,再根据排序前的索引映射回原顺序即可
- 所有计算均为NumPy向量化操作,无Python层循环,百万级以上数据量下性能表现优异
- 自动适配日期间隔不连续的场景,只会返回严格前一自然日的最大值,不会跨多日取值
内容的提问来源于stack exchange,提问作者Philippus Mercator
相关产品推荐
相关产品推荐

