共计 1782 个字符,预计需要花费 5 分钟才能阅读完成。
最近在spark上研究fp-growth算法,其中fpmodel中其中一个方法freqItemsets生成频繁集,但是生成的结果不方便用户后续统计处理,下面贴出源码
class FPGrowthModel(JavaModelWrapper):
"""
.. note:: Experimental
A FP-Growth model for mining frequent itemsets
using the Parallel FP-Growth algorithm.
>>> data = [["a", "b", "c"], ["a", "b", "d", "e"], ["a", "c", "e"], ["a", "c", "f"]]
>>> rdd = sc.parallelize(data, 2)
>>> model = FPGrowth.train(rdd, 0.6, 2)
>>> sorted(model.freqItemsets().collect())
[FreqItemset(items=[u'a'], freq=4), FreqItemset(items=[u'c'], freq=3), ...
.. versionadded:: 1.4.0
"""
@since("1.4.0")
[docs] def freqItemsets(self):
"""
Returns the frequent itemsets of this model.
"""
return self.call("getFreqItemsets").map(lambda x: (FPGrowth.FreqItemset(x[0], x[1])))
上面的类方法freqItemsets生成频繁集,但是不想在map将其转化为FreqItemset对象类型
class FreqItemset(namedtuple("FreqItemset", ["items", "freq"])):
"""
Represents an (items, freq) tuple.
.. versionadded:: 1.4.0
"""
FreqItemset是从nametuple继承,内部没有重写任何方法函数,因此在调用FreqItemset时会自动构造成相应的nametuple对象
如果你想继续定制当前的类,需要自己重写相关的方法,比如参数增加,现在默认传递的参数只有两个,你要是增加为三个或者多个该如何处理呢,这个就会涉及的到以下内容
__init__与__new__两个函数之间的关系
from collections import namedtuple
Test=namedtuple('Test', 'name age ')
class xman(Test):
def __new__(cls,a,b,c):
self=super(xman,cls).__new__(cls,a,b)
self.c=c
return self
if __name__=='__main__':
x=xman('a',11,'one')
print x
print x.c
输出结果
Test(name='a', age=11)
one
要是上述代码改为以下:
from collections import namedtuple
Test=namedtuple('Test', 'name age ')
class xman(Test):
#error
def __init__(self,a,b,c):
super(xman,self).__init__(self,a,b)
self.c=c
if __name__=='__main__':
x=xman('a',11,'one')
print x
print x.c
Traceback (most recent call last):
File "C:\Users\cuijian\Desktop\dp_blog\BlogTestCode\NametupleTest.py", line 17, in
x=xman('a',11,'one')
TypeError: __new__() takes exactly 3 arguments (4 given)
这就是实际nametuple只需要两个参数就好了,你现在在构造对象的时候传入了过多的参数,这也是说明了
__new__在__init__之前被调用,一般情况下不会去修改__new__方法,因为如果你要控制对象的构造过程就需要去修改这个函数,否则
只是初始化实例的话是不需要重写当前的函数。
正文完
请博主喝杯咖啡吧!