Создание неравномерно расположенных значений из (наложенных) распределений

Я хочу создать массив с неравномерно распределенными значениями. Расстояние должно определяться суперпозицией (например) двух нормальных распределений с разными средними значениями и значениями ширины. Для одиночного (нормального) дистрибутива мне удалось получить то, что я хочу с помощью этого поста: python, взвешенный linspace

Используя этот код:

import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

dist = stats.norm(loc=1.2, scale=0.6)
bounds = dist.cdf([0, 2])
pp = np.linspace(*bounds, num=21)
vals = dist.ppf(pp)

plt.plot(vals, [1]*vals.size, 'o')
plt.show()

Я получаю результат, который хочу для одного дистрибутива:

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

dist1 = stats.norm(loc=3, scale=2)
dist2 = stats.norm(loc=1.2, scale=0.6)

Вот как выглядит гистограмма наложенных распределений:

В качестве временного решения я создал массивы для каждого дистрибутива отдельно и добавил их вместе. Однако это не совсем то, что я хочу, потому что добавление двух отдельных массивов приводит к колебаниям размера шага между добавленными массивами (например, может случиться так, что два значения из двух разных (отдельных) массивов почти или точно идентичны).

Я также попытался определить новый дистрибутив, который наследуется от класса rv_continuous от класса scipy.stats, но мне не удалось реализовать два разных параметра среднего/ширины.

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

Заранее спасибо за любую помощь и/или комментарий!

Когда вы говорите «сложили их вместе», вы имели в виду добавление массивов numpy или их наложение, например, так vals = np.array(list(dist1.ppf(pp)) + list(dist2.ppf(pp)))? Кажется, это то, что вы ищете (при необходимости можно добавить обработку идентичных записей)?

GrimTrigger 23.12.2020 14:15
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
1
401
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете создать подкласс rv_continuous и предоставить PDF-файл, который является средним значением двух заданных PDF-файлов.

import matplotlib.pyplot as plt
import numpy as np
from scipy import stats

class sum_gaussians_gen(stats.rv_continuous):
    def _pdf(self, x):
        return (stats.norm.pdf(x, loc=3, scale=2) + stats.norm.pdf(x, loc=1.2, scale=0.6)) / 2

dist = sum_gaussians_gen()
bounds = dist.cdf([0, 7])
pp = np.linspace(*bounds, num=21)
vals = dist.ppf(pp)

plt.plot(vals, [0.5] * vals.size, 'o')
xs = np.linspace(0, 7, 500)
plt.plot(xs, dist.pdf(xs))
plt.ylim(ymin=0)
plt.show()

спасибо за ваш ответ кстати. Мне очень помог! Для подобного приложения мне нужно получить случайные числа из такого распределения. К сожалению, использование dist.rvs(size=n) для этого ОЧЕНЬ медленно. Я создал новый вопрос для этого Ускорить рисование случайных значений из наложенных усеченных нормальных распределений и подумал, что вы могли бы помочь и здесь? Еще раз спасибо!

koxx 02.02.2021 11:12

Другие вопросы по теме