如何将相同的 collections 组合在一起
How to group identical collections together
我随机抽取了一些矩阵 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})
我可以手工收集所有相同的 collections 并计算每个我有多少。例如使用上面的输出:
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})
但是,我想要的是让这些相同的 collections 组中的每一组都查看导致它们的矩阵。因此,对于上面的前两组,这将是两个矩阵,其余所有矩阵各 1 个。
执行此操作的好方法是什么?
因为你想按值对每一个进行分组,你可以用你拥有的矩阵的键 pmf-value 和值 a list/set 来创建一个新的字典,为了帮助你做到这一点,你可以使用带有 list/set 的 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)]
编辑
现在,如果您想获得产生特定 pmf-value 的矩阵 A
,请从 pmf-value 单独是不可能的,因此需要通过使用与 defaultdict 相同的方法跟踪每个产生特定 pmf-value 的矩阵来解决这个问题在使用 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())
是因为 Counter 是一个不可散列的对象,因为它是可变的,因此不能用作字典键,所以我需要 make通过将其转换为其项目的 frozenset,它是不可变的。
有了这个,现在我们有了所有具有特定 pmf
的矩阵
输出
>>> 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]]
--------------------
>>>
我随机抽取了一些矩阵 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})
我可以手工收集所有相同的 collections 并计算每个我有多少。例如使用上面的输出:
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})
但是,我想要的是让这些相同的 collections 组中的每一组都查看导致它们的矩阵。因此,对于上面的前两组,这将是两个矩阵,其余所有矩阵各 1 个。
执行此操作的好方法是什么?
因为你想按值对每一个进行分组,你可以用你拥有的矩阵的键 pmf-value 和值 a list/set 来创建一个新的字典,为了帮助你做到这一点,你可以使用带有 list/set 的 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)]
编辑
现在,如果您想获得产生特定 pmf-value 的矩阵 A
,请从 pmf-value 单独是不可能的,因此需要通过使用与 defaultdict 相同的方法跟踪每个产生特定 pmf-value 的矩阵来解决这个问题在使用 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())
是因为 Counter 是一个不可散列的对象,因为它是可变的,因此不能用作字典键,所以我需要 make通过将其转换为其项目的 frozenset,它是不可变的。
有了这个,现在我们有了所有具有特定 pmf
的矩阵输出
>>> 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]]
--------------------
>>>