как получить numpy случайно сгенерированные числа в определенном шаблоне для имитации, например, погоды в течение нескольких дней года

#python #pandas #numpy

#питон #панды #numpy

Вопрос:

Итак, мне нужно создать некоторые случайные данные для целей моделирования. Я знаю средние значения и стандартные отклонения некоторых реальных жизненных сценариев, которые я пытаюсь сгенерировать. Проблема, с которой я сталкиваюсь, заключается в том, что генерируемые случайные числа, соответствующие датам, нереалистичны. Например, погода (MinTP), она сильно колеблется, что нереально. Я хочу, чтобы числа генерировались по определенному шаблону, чтобы среднее значение отображалось в середине набора данных. Пожалуйста, смотрите Пример моего кода ниже и вывод таблицы и диаграммы рассеяния погоды за год. Я использую np.random.normal() для генерации данных, может быть, мне нужно использовать другую функцию?

 import numpy as np
import pandas as pd
import datetime

np.random.seed(2)

start2018 = datetime.datetime(2018, 1, 1)
end2018 = datetime.datetime(2018, 12, 31)
dates2018 = pd.date_range(start2018, end2018, freq='d')
synEne2018 = np.random.normal(loc=66.883795, scale=5.448145, size=365)
synMintp2018 = np.random.normal(loc=7.203288, scale=4.690315, size=365)
synCovidDailyCases2018 = np.random.normal(loc=0.0, scale=0.0, size=365)
synCovidDailyDeaths2018 = np.random.normal(loc=0.0, scale=0.0, size=365)
syn2018data = pd.DataFrame({'Date': dates2018, 'Total Daily Energy': synEne2018, 'MinTp': synMintp2018, 'DailyCovidCases': synCovidDailyCases2018, 'DailyCovidDeaths': synCovidDailyDeaths2018})
print(syn2018data)

fig, ax =plt.subplots()
sns.scatterplot(x="Date", y='MinTp', data=syn2018data[0:], color='r')
 

введите описание изображения здесь

Ответ №1:

Нормальное распределение

Нормальное распределение имеет два параметра :

  1. Подлый. В numpy.random.normal это параметр «loc».
  2. Стандартное отклонение std , которое является параметром «масштаб». На самом деле это не вся шкала ваших результирующих значений, но это распределение, которое следует нормальному закону. По сути, это означает, что 68% ваших данных будут находиться в пределах одного std от вашего mean , 95% ваших данных будут находиться в пределах двух std от вашего mean , а 99,7% ваших значений будут находиться в пределах трех std от вашего mean .

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

таблица нормального распределения

Имейте в виду , что эта таблица представляет вероятность получения значения между mean и mean z * std , а не вероятность получения значения между mean - z * std и mean z * std . Вы должны сделать 2 * p - 1 , чтобы получить последнее.

Моделирование годовых температур

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

Чтобы быть более реалистичным, я бы посоветовал получить кривую для базового minTp (с минимальным значением зимой и максимальным значением в августе), затем добавить случайность, используя нормальное распределение с loc = 0 и scale = 0.2 или около того.

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

 import math
start2018 = datetime.datetime(2018, 1, 1)
end2018 = datetime.datetime(2018, 12, 31)
dates2018 = pd.date_range(start2018, end2018, freq='d')
t_range = 4.690315 # our range
t_mean = 7.203288  # our mean
synMintp2018 = np.sin(np.arange(365)/365 * math.pi)*t_range   t_mean
synMintp2018  = np.random.normal(loc=0, scale=0.2, size=365)
...
syn2018data = pd.DataFrame({'Date': dates2018, 'Total Daily Energy': synEne2018, 'MinTp': synMintp2018, 'DailyCovidCases': synCovidDailyCases2018, 'DailyCovidDeaths': synCovidDailyDeaths2018})

fig, ax =plt.subplots()
sns.scatterplot(x="Date", y='MinTp', data=syn2018data[0:], color='r')
 

Температуры

Добавление смещения

Поскольку минимум, скорее всего, придется на январь, мы можем добавить смещение для перевода базовой кривой.

 import math
synMintp2018 = np.sin(np.arange(365)/365 * math.pi) * 4.690315   7.203288
synMintp2018 = np.roll(synMintp2018, 15) # offset in days
synMintp2018  = np.random.normal(loc=0, scale=0.2, size=365)
...
syn2018data = pd.DataFrame({'Date': dates2018, 'Total Daily Energy': synEne2018, 'MinTp': synMintp2018, 'DailyCovidCases': synCovidDailyCases2018, 'DailyCovidDeaths': synCovidDailyDeaths2018})


fig, ax =plt.subplots()
sns.scatterplot(x=syn2018data.index, y=syn2018data['MinTp'], color='r')
 

Температуры со смещением