如何为datetime时间戳添加指定范围的均匀随机噪声实现脱敏
自定义日期扰动脱敏函数实现方案
实现思路
- 不直接修改年/月/日字段避免出现非法日期(如2月30日、13月等),基于
dateutil.relativedelta实现日期偏移,自动处理闰年、大小月等边界场景,保证输出日期完全合法 - 支持单维度(年/月/日)或多维度组合配置噪声范围,每个维度的噪声值为指定区间内的均匀随机整数
- 接口对齐Cape Python的
DatePerturbation,可直接替换原有调用无需修改业务代码
依赖安装
执行以下命令安装依赖库:
pip install pandas python-dateutil
完整实现代码
import random import pandas as pd from datetime import date, datetime from dateutil.relativedelta import relativedelta class DatePerturbation: def __init__(self, frequency=None, min=None, max=None, perturb_config=None): """ 日期扰动初始化 :param frequency: 单维度扰动时指定维度,可选值为"YEAR"/"MONTH"/"DAY" :param min: 单维度扰动时的最小偏移值 :param max: 单维度扰动时的最大偏移值 :param perturb_config: 多维度扰动时的配置字典,格式示例:{"YEAR": (-1,1), "MONTH": (-3,3), "DAY": (-7,7)} """ if perturb_config is None: # 单维度配置模式 if not all([frequency, min is not None, max is not None]): raise ValueError("单维度模式需同时传入frequency、min、max参数") self.perturb_config = {frequency.upper(): (min, max)} else: # 多维度配置模式 self.perturb_config = {k.upper(): v for k, v in perturb_config.items()} # 校验维度合法性 support_dims = {"YEAR", "MONTH", "DAY"} for dim in self.perturb_config.keys(): if dim not in support_dims: raise ValueError(f"不支持的维度:{dim},仅支持YEAR、MONTH、DAY") def _perturb_single_date(self, input_date): # 处理空值 if pd.isna(input_date): return input_date # 生成各维度的随机偏移量 offset_kwargs = {} for dim, (min_offset, max_offset) in self.perturb_config.items(): offset = random.randint(min_offset, max_offset) if dim == "YEAR": offset_kwargs["years"] = offset elif dim == "MONTH": offset_kwargs["months"] = offset elif dim == "DAY": offset_kwargs["days"] = offset # 执行偏移,自动处理日期合法性 return input_date + relativedelta(**offset_kwargs) def __call__(self, date_series): # 处理pandas Series输入 return date_series.apply(self._perturb_single_date)
使用示例
示例1:单维度扰动(对齐Cape官方示例)
# 构造输入 s = pd.Series([date(year=2020, month=2, day=15)]) # 初始化扰动器:月份维度偏移-10到10 perturb = DatePerturbation(frequency="MONTH", min=-10, max=10) # 执行扰动 print(perturb(s)) # 可能输出:0 2019-07-20 # dtype: object
示例2:单维度日扰动
s = pd.Series([date(year=2021, month=9, day=23)]) # 日维度偏移-10到10 perturb = DatePerturbation(frequency="DAY", min=-10, max=10) print(perturb(s)) # 可能输出:0 2021-09-20 # dtype: object
示例3:多维度组合扰动
s = pd.Series([datetime(year=2022, month=12, day=31, hour=12, minute=30)]) # 同时配置年、月、日三个维度的噪声范围 config = { "YEAR": (-1, 1), "MONTH": (-2, 2), "DAY": (-5, 5) } perturb = DatePerturbation(perturb_config=config) print(perturb(s)) # 可能输出:0 2022-11-28 12:30:00 # dtype: datetime64[ns]
额外说明
- 如果需要固定随机结果保证可复现,可以在调用前设置随机种子:
random.seed(你的种子值) - 同时支持
datetime.date和datetime.datetime类型输入,datetime类型的时分秒部分会保留不会被修改
内容的提问来源于stack exchange,提问作者The Singularity
相关产品推荐
相关产品推荐

