unode
En RI puede crear la salida deseada haciendo:
data = c(rep(1.5, 7), rep(2.5, 2), rep(3.5, 8),
rep(4.5, 3), rep(5.5, 1), rep(6.5, 8))
plot(density(data, bw=0.5))
En python (con matplotlib) lo más cercano que obtuve fue con un histograma simple:
import matplotlib.pyplot as plt
data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8
plt.hist(data, bins=6)
plt.show()
yo también probé el parámetro normed=True pero no pudo obtener nada más que tratar de ajustar un gaussiano al histograma.
Mis últimos intentos estaban alrededor scipy.stats
y gaussian_kde
siguiendo ejemplos en la web, pero hasta ahora no he tenido éxito.
Cinco años después, cuando busqué en Google “cómo crear un diagrama de densidad del kernel usando Python”, ¡este hilo todavía aparece en la parte superior!
Hoy en día, una forma mucho más fácil de hacer esto es usar nacido en el marun paquete que proporciona muchas funciones de trazado convenientes y una buena gestión de estilo.
import numpy as np
import seaborn as sns
data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8
sns.set_style('whitegrid')
sns.kdeplot(np.array(data), bw=0.5)
-
Muchas gracias. He estado buscando algo como esto desde hace días. ¿Pueden explicar por qué el
bw=0.5
¿es dado?– Sitz Blogz
19/04/2016 a las 15:00
-
@SitzBlogz El
bw
parámetro significa ancho de banda. Estaba tratando de hacer coincidir la configuración de OP (ver su primer ejemplo de código original). Para una explicación detallada de lo quebw
controles, ver es.wikipedia.org/wiki/…. Básicamente, controla qué tan suave desea que sea el gráfico de densidad. Cuanto mayor sea el bw, más suave será.– Xin
19/04/2016 a las 19:26
-
Tengo otra consulta para pedir que mis datos sean de naturaleza discreta y estoy tratando de trazar el PDF para eso, después de leer el documento scipy entendí que PMF = PDF ¿alguna sugerencia sobre cómo trazarlo?
– Sitz Blogz
19/04/2016 a las 19:31
-
Cuando pruebo esto me sale
TypeError: slice indices must be integers or None or have an __index__ method
– endolito
16 de febrero de 2017 a las 2:26
-
Solo quiero agregar que el
bw
El parámetro está en desuso y se puede quitar como punto de partida.– Pasas
1 de diciembre de 2021 a las 16:27
justin pelar
Sven ha mostrado cómo usar la clase. gaussian_kde
de Scipy, pero notará que no se parece mucho a lo que generó con R. Esto se debe a que gaussian_kde
intenta inferir el ancho de banda automáticamente. Puedes jugar con el ancho de banda de alguna manera cambiando la función covariance_factor
del gaussian_kde
clase. Primero, esto es lo que obtienes sin cambiar esa función:
Sin embargo, si uso el siguiente código:
import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import gaussian_kde
data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8
density = gaussian_kde(data)
xs = np.linspace(0,8,200)
density.covariance_factor = lambda : .25
density._compute_covariance()
plt.plot(xs,density(xs))
plt.show()
yo obtengo
que es bastante parecido a lo que obtienes de R. ¿Qué he hecho? gaussian_kde
utiliza una función cambiable, covariance_factor
para calcular su ancho de banda. Antes de cambiar la función, el valor devuelto por covariance_factor para estos datos era de aproximadamente 0,5. Reducir esto redujo el ancho de banda. tuve que llamar _compute_covariance
después de cambiar esa función para que todos los factores se calculen correctamente. No es una correspondencia exacta con el parámetro bw de R, pero espero que lo ayude a ir en la dirección correcta.
-
A
set_bandwidth
método y unbw_method
el argumento del constructor se agregó a gaussian_kde en scipy 0.11.0 por número 1619– eddygeek
22 de enero de 2015 a las 14:46
-
Para vincular con otras respuestas, en la implementación de kde seaborn o pandas, el kde predeterminado es el
gaussian_kde
.– Ger
5 de diciembre de 2017 a las 15:01
Aziz Alto
Opción 1:
Usar pandas
gráfico de marco de datos (construido sobre matplotlib
):
import pandas as pd
data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8
pd.DataFrame(data).plot(kind='density') # or pd.Series()
Opcion 2:
Usar distplot
de seaborn
:
import seaborn as sns
data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8
sns.distplot(data, hist=False)
-
Para agregar el parámetro de ancho de banda: df.plot.density(bw_method=0.5)
– Anake
25 de agosto de 2016 a las 13:41
-
@Aziz No es necesario
pandas.DataFrame
puedo usarpandas.Series(data).plot(kind='density')
@Anake, no es necesario configurar df.plot.density como un paso separado; puede simplemente pasar en subw_method
kwarg enpd.Series(data).plot(kind='density', bw_method=0.5)
–Nate Anderson
18 de diciembre de 2017 a las 1:29
Tal vez intente algo como:
import matplotlib.pyplot as plt
import numpy
from scipy import stats
data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8
density = stats.kde.gaussian_kde(data)
x = numpy.arange(0., 8, .1)
plt.plot(x, density(x))
plt.show()
Puedes reemplazar fácilmente gaussian_kde()
por una estimación diferente de la densidad del kernel.
tetrisforjeff
El gráfico de densidad también se puede crear usando matplotlib: La función plt.hist(data) devuelve los valores de y y x necesarios para el gráfico de densidad (consulte la documentación https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.hist.html). Como resultado, el siguiente código crea un gráfico de densidad utilizando la biblioteca matplotlib:
import matplotlib.pyplot as plt
dat=[-1,2,1,4,-5,3,6,1,2,1,2,5,6,5,6,2,2,2]
a=plt.hist(dat,density=True)
plt.close()
plt.figure()
plt.plot(a[1][1:],a[0])
Este código devuelve el siguiente diagrama de densidad
-
Esta respuesta merece un voto negativo. Sin embargo, no lo haré, los votos negativos son malos, pero explique qué está mal: las estimaciones de densidad de una muestra (conjunto de puntos de datos) generalmente involucran alisado. Esto es lo que R
density()
hace la función, o lo que SciPy’sgaussian_kde()
hace. El resultado es una aproximación de la densidad continua de la que supuestamente provienen los puntos de datos, y eso es lo que buscaba el OP.–András Aszodi
13 oct 2020 a las 13:38
zarzamora
Puedes hacer algo como:
s = np.random.normal(2, 3, 1000)
import matplotlib.pyplot as plt
count, bins, ignored = plt.hist(s, 30, density=True)
plt.plot(bins, 1/(3 * np.sqrt(2 * np.pi)) * np.exp( - (bins - 2)**2 / (2 * 3**2) ),
linewidth=2, color="r")
plt.show()
-
Esta respuesta merece un voto negativo. Sin embargo, no lo haré, los votos negativos son malos, pero explique qué está mal: las estimaciones de densidad de una muestra (conjunto de puntos de datos) generalmente involucran alisado. Esto es lo que R
density()
hace la función, o lo que SciPy’sgaussian_kde()
hace. El resultado es una aproximación de la densidad continua de la que supuestamente provienen los puntos de datos, y eso es lo que buscaba el OP.–András Aszodi
13 oct 2020 a las 13:38