我有一本字典(称为dict),其键是表示要素名称的字符串,其值是表示每个要素计数的浮点数。

这是我的字典(dict)的示例:

{'11268-238-1028':2.0,'1028':10.0,'10295':2.0,'1781':2.0,'11268-238':3.0,'6967-167':1.0,'9742-232- 788”:1.0,“ 8542”:4.0,“ 238-1028”:5.0,“ 1028-122”:1.0}

在此示例中,“ 10295”被视为一度特征,“ 6967-167”被视为二度特征,而“ 9742-232-788”被视为三度特征。如果我们有“ x-x-x-x-x-x-x”,那么它将是一个七度特征。换句话说,对于任何n度特征,该特征都有(n-1)个破折号('-')。

'11268-238-1028':2.0表示3度特征'11268-238-1028'的计数为2。然后我们看到“ 11268-238”:3.0,这意味着发生了“ 11268-238” 3次。但是,这是一个重复计数问题,因为在“ 11268-238”发生的3次中,实际上有2次是由于“ 11268-238-1028”的发生。因此,我们想将“ 11268-238”的计数更改为其实际计数,即3-2 = 1。

同样,'238-1028'的实际计数也不为5,因为'238-1028'是'11268-238-1028'的一部分,而'11268-238-1028'的计数为2。因此,实数'238-1028'的计数应为(5-2 = 3)。

另一个示例是特征“ 1028”的实际数量不应为10。“ 1028”是3度特征“ 11268-238-1028”的一部分,其计数为2。“ 1028”也是一部分2度特征'238-1028'的计数为5。'1028'也是2度特征'1028-122'的一部分,其计数为1。因此,1度特征的实际计数' 1028'应该是(10-2-5-1 = 2)。

我应该使用哪种算法来解决此问题?

我考虑过将每个键转换为一组由破折号分隔的1度特征,然后针对每个集合,针对长度更大的所有其他集合进行子集成员资格测试。但是,set存储无序元素,但我关心顺序。例如,将特征'11268-238-1028'转换为集合将为(['11268','238','1028']);转换为set的另一个功能'11268-1028'将是(['11268','1028'])。如果我对这两个特征集进行子集测试,我会得出结论,[['11268','1028'])是(['11268','238','1028'])的子集。但是,功能“ 11268-1028”不是功能“ 11268-238-1028”的子集,因为在“ 11268”和“ 1028”之间,还有另一件事“ 238”,即顺序应该很重要。

那我该如何解决呢?

非常感谢!

最佳答案

防止在首次创建字典时重复计算要容易得多,而以后再撤消它就容易得多。

但是,假设该字典无法重新创建。这是一个解决方案。它不假定每个高学位特征都保证每个学位都有一个低学位对应物(也就是说,对于特征A1-A2 -...- An,您可能会缺少A1,A1-A2中的任何一个等等,直到A1-A2 -...- An-1)。如果此假设确实成立,则可以简化一些try-except

def undo_double_counting(d):
    sorted_features = sorted(d, key=lambda f: f.count('-'), reverse=True)
    for f in sorted_features:
        if '-' not in f:
            return d
        feature_below, _ = f.rsplit('-', 1)
        while True:
            try:
                d[feature_below] -= d[f]
            except KeyError:
                # if the feature one degree below isn't actually in d,
                # we keep trying lower degrees until we know that we
                # can't go lower any more (by hitting ValueError)
                try:
                    feature_below, _ = feature_below.rsplit('-', 1)
                except ValueError:
                    break
            else:
                break
    # if there are no degree-1 features in d, return here
    return d


在您的数据上尝试一下(顺便说一句,为什么要浮动而不是int?):

{'1028': 9.0,
 '1028-122': 1.0,
 '10295': 2.0,
 '11268-238': 1.0,
 '11268-238-1028': 2.0,
 '1781': 2.0,
 '238-1028': 5.0,
 '6967-167': 1.0,
 '8542': 4.0,
 '9742-232-788': 1.0}

关于python - 如何在Python中执行以下有序子集元素测试?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35247605/

10-12 21:48