我正在尝试实现apriori算法。在最后的步骤之一中,我从产品列表中生成了两个元组数组。
>>> arr1 = array([(2421,), (35682,), (30690,), ..., (18622,), (18285,), (31269,)],
dtype=object)
>>> arr2 = array([(2421, 35682), (2421, 30690), (2421, 24852), ..., (18622, 18285),
(18622, 31269), (18285, 31269)], dtype=object))
这种想法是,我需要检查arr1
中的哪个是arr2
的子元,即(2421, )
是(2421, 30690)
的子元。
我尝试了
>>> if (2421,) in (2421, 1231):
... print('Yes')
... else:
... print('No')
,我得到No
。我也尝试使用.issubset
,但得到AtributeError
。
我想知道如何在不遵循严格方式的情况下做到这一点,
>>> print(len(arr1), len(arr2))
(9258, 263616)
我正在使用带有Python 2的Jupyter笔记本。仅使用numpy,pandas和itertools。
所需的输出应为以下形式:如果我有产品1,2,3
,但我只考虑元组(1,)
和(2,)
,则从产品的所有2种组合中我需要(1,2)
而不是(1,3)
。
答案 0 :(得分:1)
如果要实现Apriori算法,则要使用实际集而不是元组。 Python有两种集合类型,set
and frozenset
,后者是不可变的,因此可以存储在字典或其他集合中。您可能希望使用后者,以便将此类集与支持评分相关联。
这肯定是apyori
project implementation使用的方法; apyory
是Apriori算法的纯Python库。
您可以对元组进行子集测试,但这对于大小为N和M的元组来说,这是一个缓慢的O(NM)操作:
def tuple_is_subset(ta, tb):
return all(tav in tb for tav in ta)
这是ta
中N个项目的完整循环,每个tav in tb
测试都需要M = len(tb)
个步骤。
您可以将元组转换为集合,但这也需要O(N)+ O(M)时间,之后子集测试将花费O(N)时间。这使整个过程花费了线性时间,但是对于小的元组,我怀疑创建新对象的不变成本将超过上述理论上更为昂贵的O(NM)all()
测试。
要使用集合,可以使用:
set(ta).issubset(tb)
set.issubset()
接受任何不可设置的迭代,代码将为测试创建一个临时的设置对象。
答案 1 :(得分:1)
欢迎2pac,
初始化
>>> arr1 = np.array([(2421,), (35682,), (30690,),(18622,), (18285,), (31269,)], dtype=object)
>>> arr2 = np.array([(2421, 35682), (2421, 30690), (2421, 24852), (18622, 18285), (18622, 31269), (18285, 31269)], dtype=object)
因此,如果您尝试询问(2421,)
是arr2
的子集
仅当True
包含大小为1的元组并且包含值arr2
时,才会返回2421
。
由于这不是您的预期行为,因此您必须遍历i
的每个arr1
项并检查是否所有i[j]
项都属于arr2[k]
快速概述
>>> arr1[0]
array([2421], dtype=object)
>>> arr1[0] in arr2
True
>>> arr1[0] in arr2[0]
True
这可以提供此功能
def is_a_subset( tuple_i, primary_tuple ):
return all( k in primary_tuple for k in tuple_i)
for tuple_i in arr1:
is_a_subset( tuple_i , arr2)
但是我建议您使用set,如果它是不可变集合(即set and frozenset)如果您逐步建立了Frozenset集合的话({>
编辑: Martijn Pieters答案以相同的方式