2014-09-23 6 views
1

Я хочу эффективно преобразовывать значения из списка (или массива numpy) в массив numpy бит: отрицательное значение должно стать 0 в новом массиве, а положительное значение a 1 в новом массиве.Преобразование положительных и отрицательных значений в битовую строку с помощью numpy.clip

Е.Г.,

>> import numpy as np 
>> np.clip([1,2,3,-1,-2], a_min=0, a_max=1) 
array([1, 1, 1, 0, 0]) 

Однако, если у меня есть поплавки в списке, этот метод сохраняет их как:

>> np.clip([1,0.45,3,-1,-2], a_min=0, a_max=1) 
array([ 1. , 0.45, 1. , 0. , 0. ]) 

Есть хороший способ обойти это поведение? Один из способов - объединить ценности. Но я бы хотел, чтобы все, что было положительным, было назначено 1. Если бы я использовал np.around(), это было бы круглым 0,45 -> 0.

ответ

4

Чтобы отобразить все, что больше 0 - 1 (и все меньше, чем 0), вы можете использовать np. where:

In [25]: np.where(np.array([1,0.45,3,-1,-2]) > 0, 1, 0) 
Out[25]: array([1, 1, 1, 0, 0]) 

или

In [29]: (np.array([1,0.45,3,-1,-2]) > 0).astype('i1') 
Out[29]: array([1, 1, 1, 0, 0], dtype=int8) 

np.where Обратите внимание, что возвращает массив с DTYPE int32 (4-байтовых целых чисел), в то время как astype('i1') возвращается массив с DTYPE int8 (1-байтовый ints).

Если вы хотите, чтобы упаковать эти двоичные значения в uint8, вы могли бы использовать np.packbits:

In [48]: x = np.array([1,0.45,3,-1,-2]) 

In [49]: np.packbits((x > 0).astype('i1')) 
Out[49]: array([224], dtype=uint8) 

In [50]: bin(224) 
Out[50]: '0b11100000' 

Или, как строка:

In [60]: np.packbits((x > 0).astype('i1')).tostring() 
Out[60]: '\xe0' 

In [62]: bin(0xe0) 
Out[62]: '0b11100000' 
+0

Nice, спасибо! Я буду принимать этот ответ, когда StackOverflow позволяет мне! – Sebastian

+1

Обратите внимание, что если производительность является проблемой, я получаю, что '(a> 0) .astype ('i1')' намного быстрее, чем 'np.where (a> 0, 1, 0)'. Разница больше, чем больше массив. Я получаю примерно вдвое быстрее для массива длиной в 100 длин, что в 10 раз быстрее для массива длиной 10 КБ. –

+0

Спасибо за примечание @RogerFan – Sebastian

2
In [21]: arr = np.array([1,0.45,3,-1,-2]) 

In [22]: np.ceil(arr.clip(0, 1)) 
Out[22]: array([ 1., 1., 1., 0., 0.])