Построение гистограммы с наложением PDF - PullRequest
3 голосов
/ 07 мая 2019

Это продолжение моих предыдущих вопросов. Вот код, с которым я играю:

import pandas as pd
import matplotlib.pyplot as plt
import scipy.stats as stats
import numpy as np
dictOne = {'Name':['First', 'Second', 'Third', 'Fourth', 'Fifth', 'Sixth', 'Seventh', 'Eighth', 'Ninth'],
           "A":[1, 2, -3, 4, 5, np.nan, 7, np.nan, 9],
           "B":[4, 5, 6, 5, 3, np.nan, 2, 9, 5],
           "C":[7, np.nan, 10, 5, 8, 6, 8, 2, 4]}
df2 = pd.DataFrame(dictOne)
column = 'B'
df2[df2[column] > -999].hist(column, alpha = 0.5)
param = stats.norm.fit(df2[column].dropna())   # Fit a normal distribution to the data
print(param)
pdf_fitted = stats.norm.pdf(df2[column], *param)
plt.plot(pdf_fitted, color = 'r')

Я пытаюсь составить гистограмму чисел в одном столбце в кадре данных - я могу сделать это - но с наложенной нормальной кривой ... что-то вроде последнего графика на здесь . Я пытаюсь заставить его работать на этом игрушечном примере, чтобы я мог применить его к своему гораздо большему набору данных по-настоящему. Код, который я вставил выше, дает мне этот график: enter image description here

Почему pdf_fitted не соответствует данным на этом графике? Как я могу наложить правильный PDF?

1 Ответ

3 голосов
/ 07 мая 2019

Вы должны построить гистограмму с density=True, если вы хотите сравнить ее с настоящим PDF. В противном случае ваша нормализация (амплитуда) будет отключена.

Кроме того, вам нужно указать значения x (в виде упорядоченного массива) при построении pdf:

fig, ax = plt.subplots()

df2[df2[column] > -999].hist(column, alpha = 0.5, density=True, ax=ax)

param = stats.norm.fit(df2[column].dropna())
x = np.linspace(*df2[column].agg([min, max]), 100) # x-values

plt.plot(x, stats.norm.pdf(x, *param), color = 'r')
plt.show()

enter image description here


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

def ECDF(data):
    n = sum(data.notnull())
    x = np.sort(data.dropna())
    y = np.arange(1, n+1) / n
    return x,y

fig, ax = plt.subplots()

plt.plot(*ECDF(df2.loc[df2[column] > -999, 'B']), marker='o')

param = stats.norm.fit(df2[column].dropna())
x = np.linspace(*df2[column].agg([min, max]), 100) # x-values

plt.plot(x, stats.norm.cdf(x, *param), color = 'r')
plt.show()

enter image description here

...