Построение 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:
Это может быть достигнуто следующим образом:
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()