我有一定数量的形式的int数组:
[a,b,c,d,e]
例如:
[2,2,1,1,2]
其中a
和b
可以是0到2的整数,c
和d
可以是0或1,e
可以是0到2。
因此,有3 * 3 * 2 * 2 * 3
:108
这种形式的可能数组。
我想为每个数组分配一个0到107的唯一整数代码。
我被卡住了,我想在数组中添加每个数字,但是有两个数组,例如:
[0,0,0,0,1] and [1,0,0,0,0]
都会加1。
有什么建议吗?
谢谢。
答案 0 :(得分:16)
您可以使用np.ravel_multi_index
:
>>> {np.ravel_multi_index(j, (3, 3, 2, 2, 3)) for j in itertools.product(*map(range, (3,3,2,2,3)))} == set(range(np.prod((3, 3, 2, 2, 3))))
True
验证:
>>> np.unravel_index(65, dims=(3, 3, 2, 2, 3))
(1, 2, 0, 1, 2)
回到另一个方向:
fileName.contains()
答案 1 :(得分:3)
这有点像将数字从不同大小的数字转换为标准整数。在base-10中,你可以有五个数字,每个数字从0到9,然后你可以通过i = a*10000 + b*1000 + c*100 + d*10 + e*1
将它们转换为一个整数。
等效地,对于十进制转换,您可以编写i = np.dot([a, b, c, d, e], bases)
,其中bases = [10*10*10*10, 10*10*10, 10*10, 10, 1]
。
你可以用你的基础做同样的事情,除了你的位置引入[3,3,2,2,3]的乘数而不是[10,10,10,10,10]。因此,您可以设置bases = [3*2*2*3, 2*2*3, 2*3, 3, 1]
(= [36,12,6,3,1]),然后使用i = np.dot([a, b, c, d, e], bases)
。请注意,如果a,b,c,d和e落在您指定的范围内,这将始终给出0到107范围内的答案。
要将i
转换回数字列表,您可以使用以下内容:
digits = []
remainder = i
for base in bases:
digit, remainder = divmod(remainder, base)
digits.append(digit)
另一方面,为了让你的生活变得简单,你可能最好使用Paul Panzer的答案,这几乎可以做同样的事情。 (我之前从未想过n位数字作为n维网格中单元格的坐标,但事实证明它们在数学上是等价的。而np.ravel是一种为每个单元格分配序列号的简单方法。)
答案 2 :(得分:3)
另一种方式,类似于多项式的Horner's method:
>>> array = [1, 2, 0, 1, 2]
>>> ranges = (3, 3, 2, 2, 3)
>>> reduce(lambda i, (a, r): i * r + a, zip(array, ranges), 0)
65
展开(&((0 * 3 + 1)* 3 + 2)* 2 + 0)* 2 + 1)* 3 + 2 = 65。
答案 3 :(得分:1)
此数据足够小,您可以简单地枚举它们:
>>> L = [[a,b,c,d,e] for a in range(3) for b in range(3) for c in range(2) for d in range(2) for e in range(3)]
>>> L[0]
[0, 0, 0, 0, 0]
>>> L[107]
[2, 2, 1, 1, 2]
如果你需要走另一条路(从数组到整数),为它创建一个查找字典,这样你就得到O(1)而不是O(n):
>>> lookup = {tuple(x): i for i, x in enumerate(L)}
>>> lookup[1,1,1,1,1]
58
答案 4 :(得分:0)
将dot-product
的向量设为:
In [210]: a1
Out[210]: array([2, 2, 1, 1, 2])
In [211]: a2
Out[211]: array([1, 0, 1, 1, 0])
In [212]: a1.dot(np.power(10, np.arange(5,0,-1)))
Out[212]: 221120
In [213]: a2.dot(np.power(10, np.arange(5,0,-1)))
Out[213]: 101100
应该产生108个唯一数字 - 使用它们的索引......
答案 5 :(得分:0)
如果数组长度不是很大,您可以先计算出重量,然后使用简单的数学公式来获取ID。 代码如下:
#Test Case
test1 = [2, 2, 1, 1, 2]
test2 = [0, 2, 1, 1, 2]
test3 = [0, 0, 0, 0, 2]
def getUniqueID(target):
#calculate out the weights first;
#When Index=0; Weight[0]=1;
#When Index>0; Weight[Index] = Weight[Index-1]*(The count of Possible Values for Previous Index);
weight = [1, 3, 9, 18, 36]
return target[0]*weight[0] + target[1]*weight[1] + target[2]*weight[2] + target[3]*weight[3] + target[4]*weight[4]
print 'Test Case 1:', getUniqueID(test1)
print 'Test Case 2:', getUniqueID(test2)
print 'Test Case 3:', getUniqueID(test3)
#Output
#Test Case 1: 107
#Test Case 2: 105
#Test Case 3: 72
#[Finished in 0.335s]