Python pandas 在给定的日期范围内生成多个随机日期

在给定的日期范围内生成多个随机日期,可以使用Python的pandas库和numpy库来实现,并将它们组织在一个DataFrame中,便于后续的数据处理和分析。本文主要介绍Python pandas中,给出开始日期和结束日期的范围,在这个范围内,随机生成日期的方法。

1、使用np.random.randint和to_datetime生成

np.random.randint 是NumPy库中的一个函数,用于生成指定范围内的随机整数。它可以接受多个参数来控制生成的随机数的范围和数量。

import pandas as pd
import numpy as np

def random_dates(start, end, n=10):
    """
    生成在给定日期范围内的多个随机日期。

    参数:
    start (pd.Timestamp): 开始日期。
    end (pd.Timestamp): 结束日期。
    n (int): 要生成的随机日期数量,默认为10。

    返回:
    pd.DatetimeIndex: 包含随机生成的日期的 DatetimeIndex 对象。
    """
    # 将日期转换为 Unix 时间戳(以秒为单位)
    start_u = start.value // 10**9
    end_u = end.value // 10**9
    
    # 生成指定数量的随机整数,然后转换为日期时间格式
    return pd.to_datetime(np.random.randint(start_u, end_u, n), unit='s')

# 示例使用
start = pd.to_datetime('2015-01-01')  # 设置开始日期
end = pd.to_datetime('2018-01-01')    # 设置结束日期

# 生成10个在2015年1月1日到2018年1月1日之间的随机日期
random_dates_list = random_dates(start, end)

# 输出生成的随机日期列表
print(random_dates_list)

或者

import pandas as pd
import numpy as np

def random_datetimes_or_dates(start, end, out_format='datetime', n=10):
    """
    生成在给定日期范围内的多个随机日期或日期时间。

    参数:
    start (pd.Timestamp): 开始日期。
    end (pd.Timestamp): 结束日期。
    out_format (str): 输出格式,'datetime' 生成日期时间,其他值生成日期。
    n (int): 要生成的随机日期或日期时间的数量,默认为10。

    返回:
    pd.DatetimeIndex: 包含随机生成的日期或日期时间的 DatetimeIndex 对象。
    """
    # 根据输出格式选择时间单位和除数
    (divide_by, unit) = (10**9, 's') if out_format == 'datetime' else (24 * 60 * 60 * 10**9, 'D')
    
    # 将日期转换为指定单位的 Unix 时间戳
    start_u = start.value // divide_by
    end_u = end.value // divide_by
    
    # 生成指定数量的随机整数,然后转换为日期时间格式
    return pd.to_datetime(np.random.randint(start_u, end_u, n), unit=unit)

# 示例使用
start = pd.to_datetime('2015-01-01')  # 设置开始日期
end = pd.to_datetime('2018-01-01')    # 设置结束日期

# 生成10个在2015年1月1日到2018年1月1日之间的随机日期时间
random_datetimes = random_datetimes_or_dates(start, end, out_format='datetime')
print("随机生成的日期时间:")
print(random_datetimes)

2、使用np.random.rand和to_timedelta生成

np.random.rand 是 NumPy 库中的一个函数,用于生成指定形状的随机数数组,这些随机数的值在 [0, 1) 区间内均匀分布。

import pandas as pd
import numpy as np

def random_dates(start, end, n, unit='D', seed=None):
    """
    生成在给定日期范围内的多个随机日期时间。

    参数:
    start (pd.Timestamp): 开始日期。
    end (pd.Timestamp): 结束日期。
    n (int): 要生成的随机日期数量。
    unit (str): 时间增量的单位,默认为天 ('D')。
    seed (int): 随机种子,默认为 None。

    返回:
    pd.DatetimeIndex: 包含随机生成的日期时间的 DatetimeIndex 对象。
    """
    # 如果没有提供随机种子,使用默认种子以保证可重复性
    if seed is None:  
        np.random.seed(0)
    
    # 计算开始日期和结束日期之间的天数
    ndays = (end - start).days + 1
    
    # 生成随机时间增量并加到开始日期上
    return pd.to_timedelta(np.random.rand(n) * ndays, unit=unit) + start

# 示例使用
np.random.seed(0)  # 设置全局随机种子
start = pd.to_datetime('2015-01-01')  # 设置开始日期
end = pd.to_datetime('2018-01-01')    # 设置结束日期

# 生成10个在2015年1月1日到2018年1月1日之间的随机日期时间
random_dates_list = random_dates(start, end, 10)

# 输出生成的随机日期时间列表
print(random_dates_list)

想要不重复的随机日期,可以用np.random.choice与replace=False:

import pandas as pd
import numpy as np

def random_dates2_unique(start, end, n, unit='D', seed=None):
    if not seed:  # from piR's answer
        np.random.seed(0)
    ndays = (end - start).days + 1
    return start + pd.to_timedelta(
        np.random.choice(ndays, n, replace=False), unit=unit
    )

# 示例使用
np.random.seed(0)  # 设置全局随机种子
start = pd.to_datetime('2015-01-01')  # 设置开始日期
end = pd.to_datetime('2018-01-01')    # 设置结束日期

# 生成10个在2015年1月1日到2018年1月1日之间的随机日期时间
random_dates_list = random_dates2_unique(start, end, 10)

# 输出生成的随机日期时间列表
print(random_dates_list)

3、使用numpy.random.choice生成

numpy.random.choice 是 NumPy 库中用于从一维数组中生成随机样本的函数。它可以用于从给定的数组中随机抽取元素,支持有放回和无放回的抽样。import pandas as pd

import numpy as np

def random_dates(start, end, n, freq, seed=None):
    """
    生成在给定日期范围和频率内的多个随机日期。

    参数:
    start (str): 开始日期字符串。
    end (str): 结束日期字符串。
    n (int): 要生成的随机日期数量。
    freq (str): 日期生成的频率(例如 'H' 表示每小时)。
    seed (list[int] 或 int): 随机种子,默认为 None。

    返回:
    pd.DatetimeIndex: 包含随机生成的日期的 DatetimeIndex 对象。
    """
    if seed is not None:
        np.random.seed(seed)
    
    # 生成指定频率的日期范围
    dr = pd.date_range(start, end, freq=freq)
    
    # 从日期范围中随机选择 n 个日期
    return pd.to_datetime(np.sort(np.random.choice(dr, n, replace=False)))

# 示例使用
start_date = '2015-01-01'  # 设置开始日期
end_date = '2018-01-01'    # 设置结束日期
number_of_dates = 10       # 生成10个随机日期
frequency = 'H'            # 频率设置为每小时
seed_value = [3, 1415]     # 设置随机种子

# 生成10个在2015年1月1日到2018年1月1日之间的随机日期(每小时频率)
random_dates_list = random_dates(start_date, end_date, number_of_dates, frequency, seed=seed_value)

# 输出生成的随机日期列表
print(random_dates_list)

4、使用numpy.random.permutation生成

numpy.random.permutation 是 NumPy 库中的一个函数,用于生成一个序列的随机排列。这个函数在数据集的随机化、洗牌等场景中非常有用。

import pandas as pd
import numpy as np

def random_dates_2(start, end, n, freq, seed=None):
    """
    在指定日期范围内,按照给定频率生成多个随机日期。

    参数:
    start (str): 开始日期,格式如 'YYYY-MM-DD'。
    end (str): 结束日期,格式如 'YYYY-MM-DD'。
    n (int): 要生成的随机日期数量。
    freq (str): 日期生成的频率,例如 'H' 表示每小时。
    seed (int or list[int]): 随机种子,默认为 None。如果给定,将保证结果可重复。

    返回:
    pd.DatetimeIndex: 包含随机生成的日期的 DatetimeIndex 对象。
    """
    if seed is not None:
        np.random.seed(seed)
    
    # 生成指定频率的日期范围
    dr = pd.date_range(start, end, freq=freq)
    
    # 生成一个排列组合的数组并选择前 n 个进行排序
    a = np.arange(len(dr))
    b = np.sort(np.random.permutation(a)[:n])
    
    # 返回生成的随机日期
    return dr[b]

# 示例使用
start = '2015-01-01'  # 设置开始日期
end = '2018-01-01'    # 设置结束日期
n = 10                # 生成10个随机日期
freq = 'H'            # 频率为每小时
seed = [3, 1415]      # 设置随机种子

# 生成10个在2015年1月1日到2018年1月1日之间的随机日期,频率为每小时
random_dates_list = random_dates_2(start, end, n, freq, seed)

# 输出生成的随机日期列表
print(random_dates_list)

推荐阅读
cjavapy编程之路首页