#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:
Нормальное распределение
Нормальное распределение имеет два параметра :
- Подлый. В numpy.random.normal это параметр «loc».
- Стандартное отклонение
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')