我會sig2int
開始..從正負數轉換爲二進制
>>> a
array([ 1., -1., 1., -1.])
>>> (a + 1)/2
array([ 1., 0., 1., 0.])
>>>
然後,你可以簡單地創建的兩個大國的陣列,由二進制和總和乘以。
>>> powers = np.arange(a.shape[-1])[::-1]
>>> np.power(2, powers)
array([8, 4, 2, 1])
>>> a = (a + 1)/2
>>> powers = np.power(2, powers)
>>> a * powers
array([ 8., 0., 2., 0.])
>>> np.sum(a * powers)
10.0
>>>
然後通過添加軸信息使它對行進行操作並依靠廣播。
def sign2int(a):
# powers of two
powers = np.arange(a.shape[-1])[::-1]
np.power(2, powers, powers)
# sign to "binary" - add one and divide by two
np.add(a, 1, a)
np.divide(a, 2, a)
# scale by powers of two and sum
np.multiply(a, powers, a)
return np.sum(a, axis = -1)
>>> b = np.array([a, a, a, a, a])
>>> sign2int(b)
array([ 11., 11., 11., 11., 11.])
>>>
我嘗試了一個4×100位陣列上,並且它似乎快
>>> a = a.repeat(100)
>>> b = np.array([a, a, a, a, a])
>>> b
array([[ 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.]])
>>> sign2int(b)
array([ 2.58224988e+120, 2.58224988e+120, 2.58224988e+120,
2.58224988e+120, 2.58224988e+120])
>>>
我將添加反向如果我可以計算它。 - 我能做的最好的依賴於一些普通的Python,沒有任何numpy矢量化魔術,我還沒有想到如何使它與一系列int整合,而不是迭代它們並一次一個地轉換它們 - 但時間依然似乎可以接受
def foo(n):
'''yields bits in increasing powers of two
bit sequence from lsb --> msb
'''
while n > 0:
n, r = divmod(n, 2)
yield r
def int2sign(n):
n = int(n)
a = np.fromiter(foo(n), dtype = np.int8, count = n.bit_length())
np.multiply(a, 2, a)
np.subtract(a, 1, a)
return a[::-1]
作品上1324:
>>> bin(1324)
'0b10100101100'
>>> a = int2sign(1324)
>>> a
array([ 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1], dtype=int8)
似乎與1.2e305工作:
>>> n = int(1.2e305)
>>> n.bit_length()
1014
>>> a = int2sign(n)
>>> a.shape
(1014,)
>>> s = bin(n)
>>> s = s[2:]
>>> all(2 * int(x) -1 == y for x, y in zip(s, a))
True
>>>
你在* real *數據集上試過了嗎?它有多大? – wwii
我期望看到的最大數據集將具有〜1000個元素的符號數組,但符號數組的數量可能在數十億之內 - 非常高的矩陣。 @wwii – user1416125
現在你提到它了,我相信只有當符號數組最多有64個元素時,它纔會起作用。 @wwii – user1416125