Pandas中双向替换值:基于价格重复条件的DataFrame数据修正
问题描述
现有一个包含日期、证券价格、基准价格的大型DataFrame,数据如下:
| date | Security_Price | Benchmark_Price |
|---|---|---|
| 2023-12-20 | 100.0 | 100.0 |
| 2023-12-21 | 105.0 | 95.0 |
| 2023-12-22 | 110.0 | 98.0 |
| 2023-12-23 | 110.0 | 100.0 |
| 2023-12-24 | 112.0 | 100.0 |
| 2023-12-25 | 112.0 | 100.0 |
| 2023-12-26 | 112.0 | 105.0 |
| 2023-12-27 | 115.0 | 107.0 |
| 2023-12-28 | 118.0 | 107.0 |
| 2023-12-29 | 120.0 | 107.0 |
| 2023-12-30 | 120.0 | 110.0 |
| 2023-12-31 | 107.0 | 108.0 |
需实现逻辑:若某一日期的Security_Price等于前一日的Security_Price,或Benchmark_Price等于前一日的Benchmark_Price,则该日期的两个价格均采用前一日的有效数值(即前一日未被替换的数值),预期处理结果如下:
| date | Security_Price | Benchmark_Price |
|---|---|---|
| 2023-12-20 | 100.0 | 100.0 |
| 2023-12-21 | 105.0 | 95.0 |
| 2023-12-22 | 110.0 | 98.0 |
| 2023-12-23 | 110.0 | 98.0 |
| 2023-12-24 | 112.0 | 100.0 |
| 2023-12-25 | 112.0 | 100.0 |
| 2023-12-26 | 112.0 | 100.0 |
| 2023-12-27 | 115.0 | 107.0 |
| 2023-12-28 | 115.0 | 107.0 |
| 2023-12-29 | 115.0 | 107.0 |
| 2023-12-30 | 120.0 | 110.0 |
| 2023-12-31 | 107.0 | 108.0 |
解决方案
可通过标记有效行+前向填充的方式实现需求,具体步骤如下:
- 标记有效行:仅当当前行的两个价格均与前一行不同时,标记为有效行
- 非有效行的价格设为缺失值
- 用前向填充将缺失值替换为最近的有效行数值
代码实现
import pandas as pd # 构造原始DataFrame data = { 'date': ['2023-12-20', '2023-12-21', '2023-12-22', '2023-12-23', '2023-12-24', '2023-12-25', '2023-12-26', '2023-12-27', '2023-12-28', '2023-12-29', '2023-12-30', '2023-12-31'], 'Security_Price': [100.0, 105.0, 110.0, 110.0, 112.0, 112.0, 112.0, 115.0, 118.0, 120.0, 120.0, 107.0], 'Benchmark_Price': [100.0, 95.0, 98.0, 100.0, 100.0, 100.0, 105.0, 107.0, 107.0, 107.0, 110.0, 108.0] } df = pd.DataFrame(data) df['date'] = pd.to_datetime(df['date']) # 标记有效行:当前行两个价格均与前一行不同,第一行默认有效 df['is_valid'] = ~((df['Security_Price'] == df['Security_Price'].shift(1)) | (df['Benchmark_Price'] == df['Benchmark_Price'].shift(1))) df.loc[0, 'is_valid'] = True # 非有效行的价格设为缺失值 df.loc[~df['is_valid'], ['Security_Price', 'Benchmark_Price']] = pd.NA # 前向填充有效数值 df = df.ffill() # 移除标记列(可选操作) df = df.drop('is_valid', axis=1) print(df)
代码说明
- 标记有效行:通过
shift(1)获取前一行价格,判断当前行是否有任一价格与前一行重复,取反后得到有效行标记,第一行无前置数据默认有效。 - 非有效行设空:将需要替换的行设为缺失值,为后续填充做准备。
- 前向填充:
ffill()自动将缺失值替换为最近的非缺失值,即前一日的有效数值,完全匹配需求逻辑。
内容的提问来源于stack exchange,提问作者Qiaodan Tian
相关产品推荐
相关产品推荐

