Как генерировать случайные даты на основе вероятности дней в Python? - PullRequest
2 голосов
/ 02 октября 2019

Я хотел бы создать случайный список длиной n на основе дат, скажем, сентября. Итак, ваш список выглядит следующим образом:

september = ["01/09/2019","02/09/2019",...,"30/09/2019"]

И я хотел бы создать список, который содержит, скажем, 1000 элементов, взятых случайным образом из september, например:

dates = ["02/09/2019","02/09/2019","07/09/2019",...,"23/09/2019"]

Я мог бы использовать что-то вроде:

dates = np.random.choice(september,1000)

Но уловка в том, что я хочу, чтобы даты выбирались на основе вероятностей дней недели. Например, у меня есть словарь, подобный следующему:

days = {"Monday":0.1,"Tuesday":0.4,"Wednesday":0.1,"Thursday":0.05,"Friday":0.05,"Saturday":0.2,"Sunday":0.1}

Так как "01/01/2019" было воскресенье, я хотел бы выбрать эту дату из september с вероятностью 0,1.

MyПопытка состояла в том, чтобы создать список, первым элементом которого является вероятность первой даты в september, и через 7 дней эта вероятность повторяется и так далее, например:

p1 = [0.1,0.1,0.4,0.1,0.05,0.05,0.2,0.1,0.1,0.4,0.1,0.05,0.05,...]

Очевидно, что это не добавляет к1, поэтому я бы сделал следующее:

p2 = [x/sum(p1) for x in p1]

А затем:

dates = np.random.choice(september,1000,p=p2)

Однако я не уверен, что это действительно работает ... Можете ли вы помочь мне?

Ответы [ 2 ]

0 голосов
/ 02 октября 2019

На самом деле я думаю, что ваш подход в порядке. Но вместо использования дат сначала получите список дат, сгруппированных по дням недели:

import numpy as np
import datetime
from collections import defaultdict

days = {"Monday":0.1,"Tuesday":0.4,"Wednesday":0.1,"Thursday":0.05,"Friday":0.05,"Saturday":0.2,"Sunday":0.1}

date_list = [(datetime.datetime(2019, 9, 1) + datetime.timedelta(days=x)) for x in range(30)]

d = defaultdict(list)

for i in date_list:
    d[i.strftime("%A")].append(i)

Теперь передайте это np.random.choice:

np.random.seed(500)

result = np.random.choice(list(d.values()),
                          p=[days.get(i) for i in list(d.keys())],
                          size=1000)

Теперь у вас есть список списковвзвешенных datetime объектов. Просто сделайте еще random.choice для предметов внутри:

final = [np.random.choice(i) for i in result]
0 голосов
/ 02 октября 2019

Если я правильно понимаю, вы хотите выбрать даты из числа дней сентября, где вероятность выбора каждой даты равна пропорционально числу раз, когда день недели этой даты появляется в сентябре - ичто вам нужно, это как назначить правильные вероятности.

Я покажу, как назначить вероятности, используя pandas (просто потому, что мне удобно).

Сначала создайте массивсоответствующих дат, используя pd.DatetimeIndex, поэтому элементы массива (в данном случае Index) являются pd.Timestamp объектами:

import pandas as pd
days_of_september = pd.DatetimeIndex(freq='1D', start='2019/09/01', end='2019/09/30')

каждой дате, мы назначаем ее день недели (от 0 до 6), используя метод .weekday (вот почему здесь удобно использовать метку времени или дату и время):

days_and_weekdays_of_september = pd.DataFrame(
    [(day, day.weekday()) for day in days_of_september], columns=('date', 'weekday'))

Подсчитать, сколько раз каждый день недели появляется в месяце:

weekday_counts = days_and_weekdays_of_september['weekday'].value_counts()

(Здесь нет большого сюрприза - все значения равны 4 или 5).

Назначьте вероятность относительно этого количества:

probability = days_and_weekdays_of_september.apply(lambda date: weekday_counts[date['weekday']], axis=1)
probability = probability/probability.sum()

И затем, с помощью pandas, вы можете выбратьоснованный на этих вероятностях (называемых "Вэйghts "здесь):

days_and_weekdays_of_september['date'].sample(n=1000, weights=probability, replace=True)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...