2017-04-03 56 views
1

假設我有一個數字的列表:位運算改變2 LSB

l = [30, 31, 32, 33] 

在二進制這會一樣

l = [00011110, 00011111, 00100000, 00100001] 

使用二進制操作我想設置至少2顯著位爲任意隨機值,但保留6位最高位位。這樣的一個例子可能是:

l_new = [00011111, 00011101, 00100010, 00100010] 

我該怎麼做,在Python中使用numpy庫?

+0

這可以很容易做足沒有NumPy的。 –

回答

1

你可以使用按位異或:

a = np.random.randint(0, 256, (10,)) 
b = np.random.randint(0, 4, a.shape) 
a 
# array([131, 79, 186, 90, 102, 179, 247, 28, 58, 60]) 
b 
# array([2, 0, 2, 1, 0, 0, 2, 0, 3, 3]) 
a^b 
# array([129, 79, 184, 91, 102, 179, 245, 28, 57, 63]) 

演示正確性:

a = np.random.randint(0, 256, (10,)) 
b = np.random.randint(0, 4, (1000000,) + a.shape) 

# show it leaves high 6 unchanged: 
print(np.all(252&a == 252&(a^b))) 
# show all low 2 values equally likely: 
print(np.abs(np.array([np.histogram(c, np.arange(5)-0.5, normed=True)[0] for c in ((a^b)&3).T])-0.25).max()) 

# True 
# 0.001595 
1

您可以使用numpy.unpackbits

l = np.random.randint(16,size=(10,)).astype(np.uint8) 
# [ 9 13 3 10 10] 

bits = np.unpackbits(l[:,np.newaxis],axis=1) 
# [[0 0 0 0 1 0 0 1] 
# [0 0 0 0 1 1 0 1] 
# [0 0 0 0 0 0 1 1] 
# [0 0 0 0 1 0 1 0] 
# [0 0 0 0 1 0 1 0]] 

bits[:,-2:] = np.random.randint(0,2,size=(bits.shape[0],2)) 
# [[0 0 0 0 1 0 0 1] 
# [0 0 0 0 1 1 0 1] 
# [0 0 0 0 0 0 1 0] 
# [0 0 0 0 1 0 0 1] 
# [0 0 0 0 1 0 0 1]] 

np.squeeze(np.packbits(bits,axis=1)) 
# [ 9 13 2 9 9]