【问题标题】:Tuple is subset of another tuple - Apriori algortihm元组是另一个元组的子集 - Apriori 算法
【发布时间】:2018-10-25 11:11:55
【问题描述】:

我正在尝试实现先验算法。在最后一个步骤中,我有两个从产品列表生成的元组数组。

>>> 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,) 那么我需要(1,2) 而不是(1,3) 来自所有2 产品组合。

【问题讨论】:

  • sourcetuple in othertuple 仅在 整个元组 包含在 othertuple 中时才有效; (42,) in ((81,), (42,)) 为真,因为第二个元组包含嵌套元组,其中一个元组等于所查找的元组。对于每值测试,您可以使用if any(v in othertuple for v in sourcetuple): 或使用sets,您可以在其中使用实际的子集测试;当setasetb 的子集 相等时,seta <= setb 为真。
  • 现在,我怀疑这是一个更大问题的一小部分,你认为你找到了解决方案。我怀疑可能有更好的方法,例如使用实际集合。
  • 是的,@MartijnPieters 我和一些同事谈过,他们告诉我改用套装。感谢您指出!

标签: python tuples jupyter-notebook subset apriori


【解决方案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() 接受任何未设置的可迭代对象,则代码会为测试创建一个临时设置对象。

【讨论】:

    【解决方案2】:

    欢迎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 的子集 仅当 arr2 包含大小为 1 的元组并包含值 2421 时才会返回 True

    由于这不是您的预期行为,您必须遍历 arr1 的每个 i 项目并检查所有 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 and frozenset),我会建议使用 set

    编辑: Martijn Pieters回答同理

    【讨论】:

      猜你喜欢
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-13
      • 2022-06-11
      • 1970-01-01
      • 1970-01-01
      • 2017-04-30
      相关资源
      最近更新 更多