Генерация данных, связанных с трендом - PullRequest
0 голосов
/ 20 сентября 2019

Я хочу создать 3 разных набора данных со столбцом, каждый из которых имеет даты (дд / мм / гггг).Эти даты должны быть в диапазоне от 3 месяцев, например, с января 2019 года по апрель 2019 года. Число для каждой даты должно представлять количество поисков.В наборе данных должно быть 2000 записей, а даты могут быть повторяемыми.Все 3 набора данных должны быть созданы таким образом, чтобы у каждого был восходящий тренд к счету, у каждого был нисходящий тренд к счету, и один был нормально распределен.

Upward trend with the time, i.e. increasing entries with time ( lower count in beginning and increasing moving forward.)
Declining trend with time i.e. decreasing entries with time (higher count in the beginning and decreasing moving forward)

Я могу создать нормальный дистрибутив с помощью плагина datagenerator

www.generatedata.com

Меня сейчас интересуетдругие 2 варианта использования, т.е. восходящий тренд и нисходящий тренд.Может кто-нибудь посоветовать мне, как сделать то же самое.Для случайного распределения я смог добиться и с помощью библиотеки фейеров.

from faker import Factory
import random
import numpy as np

faker = Factory.create()

def date_between(d1, d2):
    f = '%b%d-%Y'
    return faker.date_time_between_dates(datetime.strptime(d1, f), datetime.strptime(d2, f))

def fakerecord():
        return {'ID': faker.numerify('######'), 
                'S_date': date_between('jan01-2019', 'apr01-2019')
                }

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

Спасибо

Ответы [ 2 ]

0 голосов
/ 20 сентября 2019

Я отредактировал свой первый ответ, чтобы сделать его более понятным.

С помощью функции, приведенной ниже, вы можете установить относительные вероятности генерации поиска на начальную и конечную даты по вашему выбору.

Пример.если начальный_проб = 0,1 и конечный_проб = 1,0, то вероятность увидеть поиск в начальную дату составляет 1/10 вероятности просмотра в конечную дату

Если начальный_проб = 1,0 и конечный_проб = 0,1,тогда вероятность увидеть поиск в конечную дату равна 1/10 вероятности увидеть поиск в начальную дату

import datetime
import numpy  as np


def random_dates(start, end, starting_prob = 0.1, ending_prob = 1.0, num_samples = 2000):
    """
    Generate increasing or decreasing counts of datetimes between `start` and `end`

    Parameters:
    start: string in format'%b%d-%Y' (i.e. 'Sep19-2019')
    end : string in format'%b%d-%Y'. must be after start
    starting_prob: (float) relative probability of seeing a search on the first day
    ending_prob: (float) relative probability of seeing a search on the last day
    num_samples: number of dates in the list
    """
    start_date = datetime.datetime.strptime(start, '%b%d-%Y')
    end_date = datetime.datetime.strptime(end, '%b%d-%Y')

    # Get days between `start` and `end`
    num_days = (end_date - start_date).days

    linear_probabilities = np.linspace(starting_prob, ending_prob, num_days)

    # normalize probabilities so they add up to 1
    linear_probabilities /= np.sum(linear_probabilities)

    rand_days = np.random.choice(num_days, size = num_samples, replace = True,
             p = linear_probabilities)

    rand_date =  [(start_date + datetime.timedelta(int(rand_days[ii]))).strftime('%b%d-%Y') 
                  for ii in range(num_samples)]

    # return list of date strings
    return rand_date

Вы можете использовать функцию для генерации различных наборов дат (каждый с 20000образцы):

rdates_decreasing = random_dates("Jan01-2019", "Apr30-2019",
                      starting_prob = 1.0, ending_prob = 0.1, 
                      num_samples = 20000)

rdates_increasing = random_dates("Jan01-2019", "Apr30-2019",
                      starting_prob = 0.1, ending_prob = 1.0, 
                      num_samples = 20000)

rdates_random = random_dates("Jan01-2019", "Apr30-2019",
                      starting_prob = 1.0, ending_prob = 1.0, 
                      num_samples = 20000)

Вы можете использовать pandas для сохранения файла csv.Каждый столбец будет иметь список дат.

import pandas as pd

pd.DataFrame({'dates_decreasing': rdates_decreasing, 
              'dates_increasing': rdates_increasing, 
              'dates_random': rdates_random, 
             }).to_csv("path\to\datefile.csv", index = False)

Вы можете преобразовать свои даты в счетчики во фрейме данных следующим образом:

from collections import Counter
import matplotlib.pyplot as plt

# create dataframe with counts
df1 = pd.DataFrame({"dates_decreasing": list(Counter(rdates_decreasing).keys()), 
                      "counts_decreasing": list(Counter(rdates_decreasing).values()),
                    "dates_increasing": list(Counter(rdates_increasing).keys()), 
                      "counts_increasing": list(Counter(rdates_increasing).values()),
                    "dates_random": list(Counter(rdates_random).keys()), 
                      "counts_random": list(Counter(rdates_random).values()),
                   }) 

# convert to datetime 
df1['dates_decreasing']= pd.to_datetime(df1['dates_decreasing'])
df1['dates_increasing']= pd.to_datetime(df1['dates_increasing'])
df1['dates_random']= pd.to_datetime(df1['dates_random'])


# plot
fig, ax = plt.subplots()
ax.plot(df1.dates_decreasing, df1.counts_decreasing, "o", label = "decreasing")
ax.plot(df1.dates_increasing, df1.counts_increasing, "o", label = "increasing")
ax.plot(df1.dates_random, df1.counts_random, "o", label = "random")
ax.set_ylabel("count")
ax.legend()
fig.autofmt_xdate()
plt.show()

enter image description here

0 голосов
/ 20 сентября 2019

Вы можете сделать это, как показано ниже.

Функция тренда определяет ваш тренд, если начало выше конца, это нисходящий тренд и наоборот.Вы также можете контролировать скорость тренда, изменяя разницу между началом и концом

import numpy as np
import pandas as pd

dates = pd.date_range("2019-1-1", "2019-4-1", freq="D")

def trend(count, start_weight=1, end_weight=3):
    lin_sp = np.linspace(start_weight, end_weight, count)
    return lin_sp/sum(lin_sp)

date_trends = np.random.choice(dates,size=20000, p=trend(len(dates)))

print("Total dates", len(date_trends))

print("counts of each dates")
print(np.unique(date_trends, return_counts=True)[1])

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...