zipf分布:(齐夫定律)可以表述为:在自然语言的语料库里,一个单词出现的频率与它在频率表里的排名成反比。所以,频率最高的单词出现的频率大约是出现频率第二位的单词的2倍,而出现频率第二位的单词则是出现频率第四位的单词的2倍。这个定律被作为任何与幂定律概率分布有关的事物的参考。
遵循该定律的现象:
1.单词出现的频率
2.网页访问的概率
其公式为:P(r) = C / r^α。这里 r 表示一个单词的出现频率的排名,P(r)表示排名为r的单词的出现频率。单词频率分布中 C约等于0.1, α约等于1。
我主要是想得到1000000万条递增的key值,比如1,2,3,5,6,8,9...不是连续获得的,而是一个符合zipf分布的随机获取的1000000万条递增数据。这里我分了100块,分别从100块中获取一定数量的数据。使其从100块中获取的数据是相同的。并保存在文件中。
通过计算可知在0块中大约会抽取60多万数据,因此设置每块的数据量是700000,比如0块中就包含1-700000万条数据,从中间获取60多万数据,依次类推。获得每一块要抽取数量的值。
# -*- coding: utf-8 -*-
#P(r) = C / r^α zipf分布函数
import numpy as np
a = 2. #float类型,应该比1大
#Samples are drawn from a Zipf distribution with specified parameter a > 1
s = np.random.zipf(a, 2000)
print(s)
import matplotlib.pyplot as plt
from scipy import special
import scipy.stats as stats
count, bins, ignored = plt.hist(s[s<100], 100 , density=True)
x = np.arange(1., 100.)
y = x**(-a) / special.zetac(a)
print(x)
print(y)
plt.plot(x, y, linewidth=2, color='r')
plt.show()
sum = 0.
for num in range(0, 99):
sum = sum + y[num]
print "sum", sum
for num in range(0, 99):
y[num] = (1000000 / sum * y[num])
print(y)
plt.plot(x, y, linewidth=2, color='r')
plt.show()
sx = []
import random
sum = 0
#print random.sample(list(np.arange(0, 700000)), int(y[0]))
for num in range(0, 99):
rangenum = 700000
last = 1 + sum
sum = sum + rangenum
x = list(np.arange(last, sum))
sx.extend(random.sample(x, int(y[num]))) #append() 方法向列表的尾部添加一个新的元素。extend()方法只接受一个列表作为参数,并将该参数的每个元素都添加到原有的列表中。
sx.sort(cmp=None, key=None, reverse=False) #好用
#sorted(sx)
print sx
f = open('./test.txt', 'w')
for num in sx:
f.write(str(num))
f.close()
其中random.sample的用法需要记一下:
list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
slice = random.sample(list, 5) #从list中随机获取5个元素,作为一个片断返回
print slice
print list #原有序列并没有改变。