简体   繁体   English

带有绑定值的python itertools排列

[英]python itertools permutations with tied values

I want to find efficiently permutations of a vector which has tied values. 我想找到一个有绑定值的向量的有效排列。

Eg, if perm_vector = [0,0,1,2] I would want to obtain as output all combinations of [0,0,1,2], [0,0,2,1], [0,1,2,0] and so on, but I don't want to obtain [0,0,1,2] twice which is what the standard itertools.permutations(perm_vector) would give. 例如,如果perm_vector = [0,0,1,2]我想获得[0,0,1,2], [0,0,2,1], [0,1,2,0]所有组合作为输出[0,0,1,2], [0,0,2,1], [0,1,2,0]等等,但我不想获得[0,0,1,2]两次,这是标准的itertools.permutations(perm_vector)所给出的。

I tried the following but it works really SLOW when perm_vector grows in len: 我试过以下但是当perm_vector grows在len中perm_vector grows时它确实很慢:

vectors_list = []
for it in itertools.permutations(perm_vector):
    vectors_list.append(list(it))
df_vectors_list  = pd.DataFrame( vectors_list)
df_gb = df_vectors_list.groupby(list(df_vectors_list.columns)) 
vectors_list = pd.DataFrame(df_gb.groups.keys()).T

The question is of more general "speed-up" nature, actually. 实际上,问题是更加普遍的“加速”性质。 The main time is spent on creating the permutations of long vectors - even without the duplicity, creation of permutations of a vector of 12 unique values takes a "infinity". 主要时间用于创建长向量的排列 - 即使没有两面性,创建12个唯一值的向量的排列也需要“无穷大”。 Is there a possibility to call the itertools iteratively without accessing the entire permutations data but working on bunches of it? 是否有可能迭代地调用itertools而不访问整个排列数据但是处理它的串?

Try this if perm_vector is small: 如果perm_vector很小,请尝试这样做:

import itertools as iter
{x for x in iter.permutations(perm_vector)}

This should give you unique values, because now it becomes a set, which by default delete duplications. 这应该为您提供唯一值,因为它现在变成一个集合,默认情况下删除重复。

If perm_vector is large, you might want to try backtracking: 如果perm_vector很大,您可能想尝试回溯:

def permu(L, left, right, cache):
    for i in range(left, right):
        L[left], L[i] = L[i], L[left]
        L_tuple = tuple(L)
        if L_tuple not in cache:                
            permu(L, left + 1, right, cache)
            L[left], L[i] = L[i], L[left]
            cache[L_tuple] = 0
cache = {}
permu(perm_vector, 0, len(perm_vector), cache)
cache.keys()

How about this: 这个怎么样:

from collections import Counter

def starter(l):
    cnt = Counter(l)
    res = [None] * len(l)
    return worker(cnt, res, len(l) - 1)

def worker(cnt, res, n):
    if n < 0:
        yield tuple(res)
    else:
        for k in cnt.keys():
            if cnt[k] != 0:
                cnt[k] = cnt[k] - 1
                res[n] = k
                for r in worker(cnt, res, n - 1):
                    yield r
                cnt[k] = cnt[k] + 1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM