如何为多时间序列数据集一次性批量生成100个递增偏移的差值新列?
高效解决方案(单时间序列场景)
针对你的需求,完全不需要手动逐列创建——用pandas的assign方法配合字典推导式,一行代码就能生成所有100个差值列:
df = df.assign(**{f"{s}d": df['value'] - df['value'].shift(s) for s in range(1, 101)})
原理说明
- 字典推导式会遍历1到100的偏移量
s,为每个偏移量生成一个键(比如"1d"、"2d"),对应的值是value列减去自身偏移s行后的结果。 **操作符把这个字典拆分成assign的关键字参数,一次性将所有新列添加到原DataFrame中。- 这种方式利用了pandas的向量化操作,完全避免了Python级别的循环,处理3000万行数据的效率会比手动逐列写高几个数量级。
多时间序列场景(你的实际业务情况)
因为你提到数据包含4000个不同的时间序列,假设你的数据集有一个区分序列的列(比如series_id),只需要在分组后使用transform处理即可,同样一行代码搞定:
# 假设存在series_id列用于区分不同时间序列 df = df.assign(**{ f"{s}d": df.groupby('series_id')['value'].transform(lambda x: x - x.shift(s)) for s in range(1, 101) })
原理说明
groupby('series_id')会把数据按序列分组,确保每个序列的偏移计算是独立的,不会跨序列干扰。transform方法会将分组内的计算结果映射回原DataFrame的对应位置,保持原数据的行顺序和结构。
验证你的示例数据
用你的MWE测试前4列,执行以下代码:
df = pd.DataFrame({ "dtime": ["2022-01-01", "2022-01-02", "2022-01-03", "2022-01-04", "2022-01-05", "2022-01-06", "2022-01-07", "2022-01-08", "2022-01-09", "2022-01-10"], "value": [5,6,1,2,3,6,8,7,2,3] }) # 生成前4个差值列 df = df.assign(**{f"{s}d": df['value'] - df['value'].shift(s) for s in range(1,5)}) print(df)
输出结果和你期望的完全一致:
| dtime | value | 1d | 2d | 3d | 4d | |
|---|---|---|---|---|---|---|
| 0 | 2022-01-01 | 5 | NaN | NaN | NaN | NaN |
| 1 | 2022-01-02 | 6 | 1.0 | NaN | NaN | NaN |
| 2 | 2022-01-03 | 1 | -5.0 | -4.0 | NaN | NaN |
| 3 | 2022-01-04 | 2 | 1.0 | -4.0 | -3.0 | NaN |
| 4 | 2022-01-05 | 3 | 1.0 | 2.0 | -3.0 | -2.0 |
| 5 | 2022-01-06 | 6 | 3.0 | 4.0 | 5.0 | 0.0 |
| 6 | 2022-01-07 | 8 | 2.0 | 5.0 | 6.0 | 7.0 |
| 7 | 2022-01-08 | 7 | -1.0 | 1.0 | 4.0 | 5.0 |
| 8 | 2022-01-09 | 2 | -5.0 | -6.0 | -4.0 | -1.0 |
| 9 | 2022-01-10 | 3 | 1.0 | -4.0 | -5.0 | -3.0 |
性能小贴士
对于3000万行的大数据集:
- 这种向量化方法比循环逐列处理快得多,因为pandas底层用C实现了数值计算,避免了Python循环的开销。
- 如果内存紧张,可以分批次生成列(比如先生成1-50列,再生成51-100列),减少单次内存占用。
内容的提问来源于stack exchange,提问作者Marco_CH
相关产品推荐
相关产品推荐

