У меня есть набор данных с несколькими очень большими наблюдениями, и Меня интересует гистограмма и накопленная функция распределения, взвешенная по самим значениям.
Думайте об этом, как о наличии таблицы, которая показывает жителей для каждого города в регионе / стране. Мне все равно, сколько там городов, меня волнует только то, что, скажем, 20% населения живет в городах с населением менее 10 000 человек , 10% населения живет в крупных городах 1 миллион человек и т. Д.
Matplotlib и seaborn могут рассчитывать взвешенные гистограммы - см. Код ниже.
Моя проблема связана с CDF :
- numpy.histogram with density = True возвращает значение функции плотности вероятности в ячейках, , поэтому значения не обязательно равны 1
- matplotlib.pyplot.hist with density = True возвращает значения, сумма которых равна 1, но также отображает гистограмму, в то время как я просто хочу, чтобы значения затем строили линию самостоятельно (линия, а не гистограмма)
- statsmodels.distributions.empirical_distribution.ECDF не может принимать веса
Я пришел с помощью numpy.histogram, а затем пересчитал себя:
hist_nodens, bin_edges_nodens=np.histogram(d, 100, weights=d, density=False)
hist_nodens /= np.sum(hist_nodens)
sns.lineplot(bin_edges_nodens[1:], np.cumsum(hist_nodens))
Это работает, но мне было интересно, есть ли другие способы? Использование matplotlib.pyplot.hist для создания графика и его закрытия кажется более громоздким.
Я собрал здесь игрушечный пример. Ось у переходит в 1 на графике D, но не в C
import numpy as np
from statsmodels.distributions.empirical_distribution import ECDF
import matplotlib.pyplot as plt
import seaborn as sns
d= np.hstack([\
np.random.randint(100,1000,4000),
np.arange(10000,100000,100), \
np.linspace(200e3,900e3,20), \
1e6,2e6,4e6
])
s=np.sum(d) / 1e6
d /= 1e3
fig,ax=plt.subplots(1,5)
ax[0].set_title('A) Histogram - weighted')
sns.distplot( d, 100, kde=False, norm_hist=True, ax=ax[0], hist_kws={'weights':d} )
ax[1].set_title('B) Cumulative weighted histogram')
sns.distplot( d, 100, kde=False, norm_hist=True, ax=ax[1], hist_kws={'weights':d,'cumulative':True} )
ax[2].set_title('C) Weighted ECDF \n from np.histogram dens=True')
hist, bin_edges=np.histogram(d, 100, weights=d, density=True)
hist=np.cumsum(hist)
sns.lineplot(bin_edges[1:], hist, ax=ax[2])
ax[3].set_title('D) Weighted ECDF \n from np.histogram dens=False')
hist_nodens, bin_edges_nodens=np.histogram(d, 100, weights=d, density=False)
hist_nodens /= np.sum(hist_nodens)
sns.lineplot(bin_edges_nodens[1:], np.cumsum(hist_nodens), ax=ax[3])
py_n,py_bins,py_patches=plt.hist( d,100, weights=d, density=True, cumulative=True)
ax[4].set_title('E) ECDF - not weighted')
ecdf=ECDF( d )
x=np.linspace( min(d), max(d), num=1000 )
y=ecdf(x)
ax[4].step(x,y)