Trazado de CDF de una serie de pandas en python


¿Hay alguna manera de hacer esto? No puedo parecer una manera fácil de interactuar con pandas series con el trazado de un CDF.

Author: wolfsatthedoor, 2014-08-30

6 answers

Creo que la funcionalidad que estás buscando está en el método hist de un objeto Serie que envuelve la función hist() en matplotlib

Aquí está la documentación relevante

In [10]: import matplotlib.pyplot as plt

In [11]: plt.hist?
...
Plot a histogram.

Compute and draw the histogram of *x*. The return value is a
tuple (*n*, *bins*, *patches*) or ([*n0*, *n1*, ...], *bins*,
[*patches0*, *patches1*,...]) if the input contains multiple
data.
...
cumulative : boolean, optional, default : True
    If `True`, then a histogram is computed where each bin gives the
    counts in that bin plus all bins for smaller values. The last bin
    gives the total number of datapoints.  If `normed` is also `True`
    then the histogram is normalized such that the last bin equals 1.
    If `cumulative` evaluates to less than 0 (e.g., -1), the direction
    of accumulation is reversed.  In this case, if `normed` is also
    `True`, then the histogram is normalized such that the first bin
    equals 1.

...

Por ejemplo

In [12]: import pandas as pd

In [13]: import numpy as np

In [14]: ser = pd.Series(np.random.normal(size=1000))

In [15]: ser.hist(cumulative=True, density=1, bins=100)
Out[15]: <matplotlib.axes.AxesSubplot at 0x11469a590>

In [16]: plt.show()
 48
Author: Dan Frank,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-24 21:48:26

Un gráfico CDF o función de distribución acumulativa es básicamente un gráfico con en el eje X los valores ordenados y en el eje Y la distribución acumulativa. Por lo tanto, me gustaría crear una nueva serie con los valores ordenados como índice y la distribución acumulada como valores.

Primero cree una serie de ejemplo:

import pandas as pd
import numpy as np
ser = pd.Series(np.random.normal(size=100))

Ordenar la serie:

ser = ser.sort_values()

Ahora, antes de continuar, añada de nuevo el último (y mayor) valor. Este paso es importante especialmente para tamaños de muestra pequeños con el fin de obtener un CDF imparcial:

ser[len(ser)] = ser.iloc[-1]

Crear una nueva serie con los valores ordenados como índice y la distribución acumulada como valores:

cum_dist = np.linspace(0.,1.,len(ser))
ser_cdf = pd.Series(cum_dist, index=ser)

Finalmente, trace la función como pasos:

ser_cdf.plot(drawstyle='steps')
 13
Author: kadee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-06 17:20:15

Esta es la forma más fácil.

import pandas as pd
df = pd.Series([i for i in range(100)])
df.hist( cumulative = True )

Imagen del histograma acumulativo

 7
Author: wroscoe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-19 13:52:36

Para mí, esto me pareció una manera simple de hacerlo:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

heights = pd.Series(np.random.normal(size=100))

# empirical CDF
def F(x,data):
    return float(len(data[data <= x]))/len(data)

vF = np.vectorize(F, excluded=['data'])

plt.plot(np.sort(heights),vF(x=np.sort(heights), data=heights))
 2
Author: annon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-18 04:01:43

Vine aquí buscando una trama como esta con barras y una línea CDF: introduzca la descripción de la imagen aquí

Se puede lograr así:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
series = pd.Series(np.random.normal(size=10000))
fig, ax = plt.subplots()
ax2 = ax.twinx()
n, bins, patches = ax.hist(series, bins=100, normed=False)
n, bins, patches = ax2.hist(
    series, cumulative=1, histtype='step', bins=100, color='tab:orange')
plt.savefig('test.png')

Si desea eliminar la línea vertical, se explica cómo lograrlo aquí. O simplemente podrías hacer:

ax.set_xlim((ax.get_xlim()[0], series.max()))

También vi una solución elegante aquí sobre cómo hacerlo con seaborn.

 1
Author: tommy.carstensen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-30 00:13:38

Encontré otra solución en los Pandas "puros", que no requiere especificar el número de contenedores para usar en un histograma:

import pandas as pd
import numpy as np # used only to create example data

series = pd.Series(np.random.normal(size=10000))

cdf = series.value_counts().sort_index().cumsum()
cdf.plot()
 1
Author: jk.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-27 09:14:16