Построение CDF серии панд в python

есть ли способ сделать это? Я не могу показаться простым способом сопряжения серии pandas с построением CDF.

6 ответов


Я считаю, что функциональность, которую вы ищете, находится в методе hist объекта Series, который обертывает функцию hist () в matplotlib

вот соответствующая документация

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.

...
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()

график CDF или кумулятивной функции распределения в основном представляет собой график с отсортированными значениями по оси X и кумулятивным распределением по оси Y. Итак, я бы создал новую серию с отсортированными значениями в качестве индекса и кумулятивным распределением в качестве значений.

сначала создать пример:

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

Сортировать серии:

ser = ser.sort_values()

теперь, прежде чем продолжить, снова добавьте последнее (и наибольшее) значение. Этот шаг особенно важен для небольшие размеры выборки для того, чтобы получить объективную СГО:

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

создайте новый ряд с отсортированными значениями в качестве индекса и кумулятивным распределением в качестве значений:

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

наконец, постройте функцию как шаги:

ser_cdf.plot(drawstyle='steps')

Это самый простой способ.

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

изображение кумулятивной гистограммы


для меня это казалось простым способом сделать это:

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))

Я пришел сюда в поисках сюжета, как это с барами и линия CDF: enter image description here

Это может быть достигнуто следующим образом:

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')

Если вы хотите удалить вертикальную линию, то объясняется, как это сделать здесь. Или вы могли бы просто сделать:

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

Я также видел элегантное решение здесь о том, как сделать это с seaborn.


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

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()