2017-04-20 48 views
0

早上好,CDF Python中没有显示正确

在Python,我有一本字典(称为packet_size_dist)具有以下值:

34 => 0.00909909009099 
42 => 0.02299770023 
54 => 0.578742125787 
58 => 0.211278872113 
62 => 0.00529947005299 
66 => 0.031796820318 
70 => 0.0530946905309 
74 => 0.0876912308769 

注意,值== 1的总和。

我试图生成一个CDF,我成功地做了,但它看起来错了,我想知道如果我正在生成它不正确。有问题的代码是:

sorted_p = sorted(packet_size_dist.items(), key=operator.itemgetter(0)) 
yvals = np.arange(len(sorted_p))/float(len(sorted_p)) 
plt.plot(sorted_p, yvals) 
plt.show() 

但结果图如下所示: CDF of Packet Distribution

似乎这不是在字典完全匹配的值。有任何想法吗?我还看到图中左侧的模糊的绿线,我不知道它是什么。例如,图表描述了70%的数据包大小发生在大约78%的时间内,在我的字典中,它表示为5%的时间。

+0

我试图澄清我的答案的第一部分。 –

回答

1

使用numpy可以让所有事情变得更容易。所以首先你可以将你的字典转换成一个2列numpy数组。然后,您可以按第一列对其进行排序。最后,简单地计算第二列的累计和并将其与第一列进行比较。

dic = { 34 : 0.00909909009099, 
     42 : 0.02299770023, 
     54 : 0.578742125787, 
     58 : 0.211278872113, 
     62 : 0.00529947005299, 
     66 : 0.031796820318, 
     70 : 0.0530946905309, 
     74 : 0.0876912308769 } 

import numpy as np 
import matplotlib.pyplot as plt 

data = np.array([[k,v] for k,v in dic.iteritems()]) # use dic.items() for python3 
data = data[data[:,0].argsort()] 
cdf = np.cumsum(data[:,1]) 

plt.plot(data[:,0], cdf) 

plt.show() 

enter image description here

+0

谢谢!但是,这个图表是不是表示值“74”出现在大约0.95的时间?我认为在CDF发行版中,总和需要== 1.0,如果你总结字典值键,他们会这样做,但图表似乎并没有很好地表现出来。但是你的代码在我的最后复制很好! – Nicholas

+0

不,累积密度函数(CDF)为您提供查找低于某个值x的值的概率。因此图形告诉你所有值的100%小于或等于74;或者更好的例子,找到小于或等于58的值的概率是〜82%。如果你真的想要一个概率密度函数(PDF),它可以给出在某个值x处或附近找到一个值的概率,那么你可以绘制你的数据,因为它已经被归一化了。 – ImportanceOfBeingErnest

+0

啊,好的,谢谢!不,CDF是我想要的,我只是在我心中转换他们的意思。非常感激。 – Nicholas

1

这不是直接回答你的问题。然而,我认为我应该指出,你的数据来自一个离散的随机变量(而不是一个连续的变量),因此,在一些情况下,用一系列线段表示它们可能有点误导。在cumulative distribution function中的表示可能是矫枉过正。我提供以下简化。

enter image description here

的 'x' 表示截断。点表示闭合间隔的闭合端。

这是代码。我没想过用np.cumsum

import numpy as np 
import pylab as pl 
from matplotlib import collections as mc 

p = [0.00909909009099,0.02299770023,0.578742125787,0.211278872113,0.00529947005299,0.031796820318,0.0530946905309,0.0876912308769] 
cumSums = [0] + [sum(p[:i]) for i in range(1,len(p)+1)] 
counts = [30,34,42,54,58,62,66,70,74,80] 

lines =[[(counts[i],cumSums[i]),(counts[i+1],cumSums[i])] for i in range(-1+len(counts))] 

lc = mc.LineCollection(lines, linewidths=2) 
fig, ax = pl.subplots() 
ax.add_collection(lc) 

pl.plot([30, 80],[0, 1],'bx') 
pl.plot(counts[1:-1], cumSums[1:], 'bo') 

ax.autoscale() 
ax.margins(0.1) 

pl.show() 

这更像是你似乎想要的情节。 (更正,我希望。)

enter image description here

对于其中的代码。

import numpy as np 
import pylab as pl 
from matplotlib import collections as mc 
from sys import exit 

p = [0.00909909009099,0.02299770023,0.578742125787,0.211278872113,0.00529947005299,0.031796820318,0.0530946905309,0.0876912308769] 
cumSums = [sum(p[:i]) for i in range(1,len(p)+1)] 
counts = [34,42,54,58,62,66,70,74] 

lines = [[(counts[i],cumSums[i]),(counts[i+1],cumSums[i+1])] for i in range(-1+len(p))] 

lc = mc.LineCollection(lines, linewidths=2) 
fig, ax = pl.subplots() 
ax.add_collection(lc) 
ax.autoscale() 
ax.margins(0.1) 

pl.show() 
+0

这个解决方案很奇怪。你发明了一些数字(33和90),这些数字并不在数据中,并使得显示的CDF完全错误。 – ImportanceOfBeingErnest

+0

@ImportanceOfBeingErnest:用你惯常的机智来表达。无论如何,不​​是真的。 –

+0

所以你想说第二张图中的曲线正确代表了这个问题的数据? – ImportanceOfBeingErnest