Python 如何将相同的集合分组在一起

Python 如何将相同的集合分组在一起,python,math,probability,Python,Math,Probability,我随机抽取大量矩阵a,每一个矩阵都计算Ax的概率质量函数(pmf)。x是随机的,元素从+-1开始,A是矩阵,元素从+-1开始。到目前为止,我的代码如下所示: from collections import Counter import numpy as np import itertools def pmf(L): C = Counter(L) total = float(sum(C.values())) for key in C: C[key]/=to

我随机抽取大量矩阵a,每一个矩阵都计算Ax的概率质量函数(pmf)。x是随机的,元素从+-1开始,A是矩阵,元素从+-1开始。到目前为止,我的代码如下所示:

from collections import Counter
import numpy as np
import itertools

def pmf(L):
    C = Counter(L)
    total = float(sum(C.values()))
    for key in C:
        C[key]/=total
    return C

N = 10

h = 2
n = 2**h
X = np.array(list(itertools.product([-1,1],repeat = n))).T

for _ in xrange(N):
    A = (np.random.randint(2, size=(h,n)))*2-1
    B = np.dot(A,X)
    probs = pmf([tuple(x) for x in B.T.tolist()])
    print probs
例如,这将提供:

Counter({(0, 0): 0.375, (2, 2): 0.25, (-2, -2): 0.25, (-4, -4): 0.0625, (4, 4): 0.0625})
Counter({(0, 0): 0.25, (-2, 2): 0.125, (2, 2): 0.125, (2, -2): 0.125, (-2, -2): 0.125, (0, 4): 0.0625, (-4, 0): 0.0625, (4, 0): 0.0625, (0, -4): 0.0625})
Counter({(-2, 0): 0.1875, (0, 2): 0.1875, (2, 0): 0.1875, (0, -2): 0.1875, (-2, -4): 0.0625, (4, 2): 0.0625, (2, 4): 0.0625, (-4, -2): 0.0625})
Counter({(0, 2): 0.1875, (2, 0): 0.1875, (0, -2): 0.1875, (-2, 0): 0.1875, (-4, -2): 0.0625, (-2, -4): 0.0625, (4, 2): 0.0625, (2, 4): 0.0625})
Counter({(0, 0): 0.25, (-2, -2): 0.125, (-2, 2): 0.125, (2, 2): 0.125, (2, -2): 0.125, (-4, 0): 0.0625, (0, 4): 0.0625, (0, -4): 0.0625, (4, 0): 0.0625})
Counter({(0, 0): 0.25, (2, -2): 0.125, (2, 2): 0.125, (-2, -2): 0.125, (-2, 2): 0.125, (-4, 0): 0.0625, (0, 4): 0.0625, (0, -4): 0.0625, (4, 0): 0.0625})
Counter({(-2, 0): 0.1875, (2, 0): 0.1875, (0, -2): 0.1875, (0, 2): 0.1875, (-4, 2): 0.0625, (4, -2): 0.0625, (-2, 4): 0.0625, (2, -4): 0.0625})
Counter({(-2, 0): 0.1875, (2, 0): 0.1875, (0, -2): 0.1875, (0, 2): 0.1875, (-4, 2): 0.0625, (4, -2): 0.0625, (-2, 4): 0.0625, (2, -4): 0.0625})
Counter({(2, 0): 0.1875, (0, -2): 0.1875, (0, 2): 0.1875, (-2, 0): 0.1875, (-4, -2): 0.0625, (-2, -4): 0.0625, (2, 4): 0.0625, (4, 2): 0.0625})
Counter({(0, 0): 0.25, (-2, -2): 0.125, (-2, 2): 0.125, (2, 2): 0.125, (2, -2): 0.125, (-4, 0): 0.0625, (0, 4): 0.0625, (0, -4): 0.0625, (4, 0): 0.0625})
我可以手工收集所有相同的收藏,并计算每个收藏的数量。例如,使用上述输出:

2     Counter({(-2, 0): 0.1875, (2, 0): 0.1875, (0, -2): 0.1875, (0, 2): 0.1875, (-4, 2): 0.0625, (4, -2): 0.0625, (-2, 4): 0.0625, (2, -4): 0.0625})
2     Counter({(0, 0): 0.25, (-2, -2): 0.125, (-2, 2): 0.125, (2, 2): 0.125, (2, -2): 0.125, (-4, 0): 0.0625, (0, 4): 0.0625, (0, -4): 0.0625, (4, 0): 0.0625})
1     Counter({(-2, 0): 0.1875, (0, 2): 0.1875, (2, 0): 0.1875, (0, -2): 0.1875, (-2, -4): 0.0625, (4, 2): 0.0625, (2, 4): 0.0625, (-4, -2): 0.0625})
1     Counter({(2, 0): 0.1875, (0, -2): 0.1875, (0, 2): 0.1875, (-2, 0): 0.1875, (-4, -2): 0.0625, (-2, -4): 0.0625, (2, 4): 0.0625, (4, 2): 0.0625})
1     Counter({(0, 2): 0.1875, (2, 0): 0.1875, (0, -2): 0.1875, (-2, 0): 0.1875, (-4, -2): 0.0625, (-2, -4): 0.0625, (4, 2): 0.0625, (2, 4): 0.0625})
1     Counter({(0, 0): 0.375, (2, 2): 0.25, (-2, -2): 0.25, (-4, -4): 0.0625, (4, 4): 0.0625})
1     Counter({(0, 0): 0.25, (2, -2): 0.125, (2, 2): 0.125, (-2, -2): 0.125, (-2, 2): 0.125, (-4, 0): 0.0625, (0, 4): 0.0625, (0, -4): 0.0625, (4, 0): 0.0625})
1     Counter({(0, 0): 0.25, (-2, 2): 0.125, (2, 2): 0.125, (2, -2): 0.125, (-2, -2): 0.125, (0, 4): 0.0625, (-4, 0): 0.0625, (4, 0): 0.0625, (0, -4): 0.0625})
然而,我希望这些相同集合的每一组都能看到导致它们的矩阵。这就是上面前两组的两个矩阵,其余的各1个矩阵


做这件事的好方法是什么?

当您想按值对每一个进行分组时,您可以使用pmf值键创建一个新的dict,并将该值设置为矩阵的列表/集合,为此,您可以使用带有列表/集合的defaultdict。像这样

from collections import Counter, defaultdict

test = Counter({(0, 0): 0.25, (-2, -2): 0.125, (-2, 2): 0.125, (2, 2): 0.125, (2, -2): 0.125, (-4, 0): 0.0625, (0, 4): 0.0625, (0, -4): 0.0625, (4, 0): 0.0625})

result = defaultdict(list)
for k,v in test.iteritems():
    result[v].append(k)
print result

#or more readable 
for k,v in result.iteritems():
    print k,v
输出

0.25 [(0, 0)]
0.125 [(2, 2), (2, -2), (-2, -2), (-2, 2)]
0.0625 [(-4, 0), (0, 4), (0, -4), (4, 0)]
>>> for k,v in result.items():
        print k
        for A in v:
            print A
            print ""
        print "--------------------"


frozenset({((-4, 2), 0.0625), ((2, 0), 0.1875), ((4, -2), 0.0625), ((0, 2), 0.1875), ((-2, 4), 0.0625), ((0, -2), 0.1875), ((-2, 0), 0.1875), ((2, -4), 0.0625)})
[[ 1  1 -1  1]
 [-1 -1  1  1]]

[[ 1  1 -1 -1]
 [-1  1  1  1]]

--------------------
frozenset({((2, 0), 0.1875), ((-2, -4), 0.0625), ((2, 4), 0.0625), ((0, 2), 0.1875), ((4, 2), 0.0625), ((0, -2), 0.1875), ((-2, 0), 0.1875), ((-4, -2), 0.0625)})
[[-1  1  1 -1]
 [ 1  1  1 -1]]

[[ 1  1  1 -1]
 [ 1 -1  1 -1]]

[[-1  1 -1  1]
 [-1  1  1  1]]

--------------------
frozenset({((0, 0), 0.25), ((-2, 2), 0.125), ((2, -2), 0.125), ((0, -4), 0.0625), ((0, 4), 0.0625), ((-4, 0), 0.0625), ((2, 2), 0.125), ((-2, -2), 0.125), ((4, 0), 0.0625)})
[[-1 -1 -1  1]
 [ 1  1 -1  1]]

[[-1  1  1 -1]
 [-1 -1 -1 -1]]

[[-1 -1 -1 -1]
 [ 1 -1  1 -1]]

[[ 1  1 -1  1]
 [ 1 -1  1  1]]

[[ 1  1  1  1]
 [-1 -1  1  1]]

--------------------
>>> 
编辑

现在,如果你想得到产生特定pmf值的矩阵
A
,仅仅从pmf值中得到是不可能的,因此,需要通过使用与以前相同的defaultdict方法(以pmf为键)跟踪产生特定pmf值的每个矩阵,并使用该pmf对矩阵列表进行赋值来解决此问题,如下所示:

from collections import Counter, defaultdict
import numpy as np
import itertools

def pmf(L):
    C = Counter(L)
    total = float(sum(C.values()))
    for key in C:
        C[key]/=total
    return C

N = 10

h = 2
n = 2**h
X = np.array(list(itertools.product([-1,1],repeat = n))).T

result = defaultdict(list)

for _ in xrange(N):
    A = (np.random.randint(2, size=(h,n)))*2-1
    B = np.dot(A,X)
    probs = pmf([tuple(x) for x in B.T.tolist()])
    print probs
    result[ frozenset(probs.items()) ].append( A ) #append the one you need
现在这部分
frozenset(probs.items())
是因为计数器是不可损坏的对象,因为它是可变的,因此不能用作dict键,所以我需要通过将其转换为其项的frozenset来使其不可更改

有了这个,我们就有了所有具有特定pmf的矩阵

输出

0.25 [(0, 0)]
0.125 [(2, 2), (2, -2), (-2, -2), (-2, 2)]
0.0625 [(-4, 0), (0, 4), (0, -4), (4, 0)]
>>> for k,v in result.items():
        print k
        for A in v:
            print A
            print ""
        print "--------------------"


frozenset({((-4, 2), 0.0625), ((2, 0), 0.1875), ((4, -2), 0.0625), ((0, 2), 0.1875), ((-2, 4), 0.0625), ((0, -2), 0.1875), ((-2, 0), 0.1875), ((2, -4), 0.0625)})
[[ 1  1 -1  1]
 [-1 -1  1  1]]

[[ 1  1 -1 -1]
 [-1  1  1  1]]

--------------------
frozenset({((2, 0), 0.1875), ((-2, -4), 0.0625), ((2, 4), 0.0625), ((0, 2), 0.1875), ((4, 2), 0.0625), ((0, -2), 0.1875), ((-2, 0), 0.1875), ((-4, -2), 0.0625)})
[[-1  1  1 -1]
 [ 1  1  1 -1]]

[[ 1  1  1 -1]
 [ 1 -1  1 -1]]

[[-1  1 -1  1]
 [-1  1  1  1]]

--------------------
frozenset({((0, 0), 0.25), ((-2, 2), 0.125), ((2, -2), 0.125), ((0, -4), 0.0625), ((0, 4), 0.0625), ((-4, 0), 0.0625), ((2, 2), 0.125), ((-2, -2), 0.125), ((4, 0), 0.0625)})
[[-1 -1 -1  1]
 [ 1  1 -1  1]]

[[-1  1  1 -1]
 [-1 -1 -1 -1]]

[[-1 -1 -1 -1]
 [ 1 -1  1 -1]]

[[ 1  1 -1  1]
 [ 1 -1  1  1]]

[[ 1  1  1  1]
 [-1 -1  1  1]]

--------------------
>>> 

我没有投票关闭它,但我可以看到有人投票认为它“不清楚你在问什么”——所以也许你可以澄清一点。@johncolman我更新了问题。谢谢你,但这不是我想要的。我已经更新了问题。现在我不明白你想要什么,你想从计数器中得到生成这些计数器的矩阵吗?如果是的话,那是女巫吗?A或B或两者都有?我做了编辑,现在,如果我理解正确,那就是你想要的,对吗?